E.g. I have a List of objects, List A, and its initialized with 7 elements. Each element is ordered by an integer field called "elementOrder".
How can I take a new List of the same objects, List B, and merge them into List A based on the "elementOrder"?
Note that List B contains duplicates of List A and I only want to merge unique elements of List B into List A.
Thanks you.
S
//copy ListA element on a new list
var newList = new ArrayList<ElementType>(ListA)
//add B elements to new list
newList.addAll(ListB)
//order the new list with elementOrder column
newList = newList.orderBy( \ element -> element.elementOrder)
Q : List B contains duplicates of List A and I only want to merge unique elements of List B into List A
R : you must use Blocks (lambda expressions) to filter duplicates elements
//copy ListA element on a new list
var newList = new ArrayList<ElementType>(ListA)
//filter B elements not in ListA
var FiltredListB = ListB.where( \ element -> not ListA.contains(element))
//add FiltredListB elements to new list
newList.addAll(FiltredListB)
//order the new list with elementOrder column
newList = newList.orderBy( \ element -> element.elementOrder)
Related
I need a query which does the following things:
Insert a varaible number of nodes if they don't exist
If there isn't already a node which has a relation to all nodes added in 1 create this node and connect it to nodes from one
The general idea is that the variable number of nodes describe a unique event which I want to aggregate by inserting the new node.
So if I first insert 4 nodes by this
MERGE (k:type1 {data: "data1"})
MERGE (a:type2 {data: "data2"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS myList
CALL apoc.lock.nodes(myList) // let's lock ahead this time
WITH head(myList) as first, myList
OPTIONAL MATCH (d:SomeLabel)-[:REL]->(first)
WHERE all(node in tail(myList) WHERE (d)-[:REL]->(node))
WITH first, myList
WHERE d IS NULL
MERGE (d:SomeLabel)-[:REL]->(first)
FOREACH (node in tail(myList) | MERGE (d)-[:REL]->(node))
If I change the first node the graph looks as expected:
MERGE (a:type2 {data: "data2"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS myList
CALL apoc.lock.nodes(myList) // let's lock ahead this time
WITH head(myList) as first, myList
OPTIONAL MATCH (d:SomeLabel)-[:REL]->(first)
WHERE all(node in tail(myList) WHERE (d)-[:REL]->(node))
WITH first, myList
WHERE d IS NULL
MERGE (d:SomeLabel)-[:REL]->(first)
FOREACH (node in tail(myList) | MERGE (d)-[:REL]->(node))
Correct graph
However when changing for example the content of the second node, a new common node is not added
MERGE (k:type1 {data: "data1"})
MERGE (a:type2 {data: "data22"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS myList
CALL apoc.lock.nodes(myList) // let's lock ahead this time
WITH head(myList) as first, myList
OPTIONAL MATCH (d:SomeLabel)-[:REL]->(first)
WHERE all(node in tail(myList) WHERE (d)-[:REL]->(node))
WITH first, myList
WHERE d IS NULL
MERGE (d:SomeLabel)-[:REL]->(first)
FOREACH (node in tail(myList) | MERGE (d)-[:REL]->(node))
Incorrect graph
Also, after this has been done I want to add another node connected to the new common node
I used #Graphileon's answer for my solution
MERGE (a:type2 {data: "data2"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS things
OPTIONAL MATCH (c:Collection)
WHERE apoc.coll.isEqualCollection([(c)-[:REL]->(thing)|thing],things)
WITH things,COALESCE(id(c),-1) AS idC, id(c) as center
CALL apoc.do.when(
idC = -1,
'CREATE (c:Collection) '
+ 'FOREACH(m IN $things | MERGE (c)-[:REL]->(m) ) '
+ 'MERGE (s:sample)-[:REL]->(c)',
'',
{things:things}
) YIELD value
RETURN value.node as node;
Did you consider this approach:
WITH ['a','b','c','d'] AS thingNames
FOREACH( thingName in thingNames |
MERGE (n:Thing {name:thingName})
)
WITH thingNames
MATCH (n:Thing) WHERE n.name IN thingNames
WITH COLLECT(n) AS things
OPTIONAL MATCH (c:Collection)
WHERE apoc.coll.isEqualCollection([(c)-[:REL]->(thing)|thing],things)
WITH things,c,COALESCE(id(c),-1) AS idC
CALL apoc.do.when(
idC = -1,
'CREATE (c:Collection) '
+' FOREACH(m IN $things | MERGE (c)-[:REL]->(m) )'
+' RETURN c',
'',
{things:things}
) YIELD value
RETURN COALESCE(c, value.c) AS collectionNode
it creates a new :Collection node for every new combination of Things
I want to get only first 10 or possibly n rows in-memory as java list using copyFromRealm method. Consider like this:
RealmResults<RecentViewItem> results = realm.where(RecentViewItem.class).findAllSorted("updatedAt", Sort.DESCENDING);
// This will load all rows in-memory list
List<RecentViewItem> list = realm.copyFromRealm(results);
// But I want only first n rows without running any loop.
UPDATE:
Since RealmResult extends AbstractList -
RealmResults<RecentViewItem> results =
realm.where(RecentViewItem.class)
.findAllSorted("updatedAt", Sort.DESCENDING);
List<RecentViewItem> temp = results.subList(0, maxNoRecentViewItem); // Still list of RealmProxyObject
List<RecentViewItem> list = realm.copyFromRealm(temp); // List of RecentViewItem Object
I am working on a OCaml motion detection program. It analyzes two images and detects if there was motion. One part requires me summing a row of values and then also summing an entire image. This is what I have currenly:
let rec sumImRow(maskedrow) =
match maskedrow with
| [] -> 0
| mskRhd::mskRtl -> mskRhd + (sumImRow mskRtl)
;;
let rec sumImage(maskedimage) =
match maskedimage with
| mskRhd::mskRtl -> (sumImRow mskRhd)::(sumImage mskRtl)
| _ -> []
;;
and the given value is int list list -> int list = <fun>.
I don't quite understand why this is giving me int list.
tl;dr: You construct a new list instead of summing the integers.
Well, we can agree that sumImRow has type int list -> int as it takes elements from the list and then return their sum.
sumImage will have a list argument as it deconstructs it in the pattern matching. It then returns the list of result of sumImRow, meaning sumImage gets as argument a list of what sumImRow takes and returns a list of results. So we indeed have int list list -> int list.
You can avoid that by replacing :: with + and [] with 0 in sumImage's matching result.
You can also make a more improved code by using List.fold_left:
let sumImRow l = List.fold_left (+) 0 l;;
let sumImage l = List.fold_left (List.fold_left (+)) 0 l;;
The two return values of sumImage are both lists. So naturally its return type is a list.
(Most likely you should be using + rather than :: in sumImage. And the base case should be 0 rather than [].)
I am stuck at creating a matrix of a matrix (vector in this case)
What I have so far
index = zeros(size(A)) // This is some matrix but isn't important to the question
indexIndex = 1;
for rows=1:length(R)
for columns=1:length(K)
if(A(rows,columns)==x)
V=[rows columns]; // I create a vector holding the row + column
index(indexIndex) = V(1,2) // I want to store all these vectors
indexIndex = indexIndex + 1
end
end
end
I have tried various ways of getting the information out of V (such as V(1:2)) but nothing seems to work correctly.
In other words, I'm trying to get an array of points.
Thanks in advance
I do not understand your question exactly. What is the size of A? What is x, K and R? But under some assumptions,
Using list
You could use a list
// Create some matrix A
A = zeros(8,8)
//initialize the list
index = list();
// Get the dimensions of A
rows = size(A,1);
cols = size(A,2);
x = 0;
for row=1:rows
for col=1:cols
if(A(row,col)==x)
// Create a vector holding row and col
V=[row col];
// Append it to list using $ (last index) + 1
index($+1) = V
end
end
end
Single indexed matrices
Another approach would be to make use of the fact an multi-dimensional matrix can also be indexed by a single value.
For instance create a random matrix named a:
-->a = rand(3,3)
a =
0.6212882 0.5211472 0.0881335
0.3454984 0.2870401 0.4498763
0.7064868 0.6502795 0.7227253
Access the first value:
-->a(1)
ans =
0.6212882
-->a(1,1)
ans =
0.6212882
Access the second value:
-->a(2)
ans =
0.3454984
-->a(2,1)
ans =
0.3454984
So that proves how the single indexing works. Now to apply it to your problem and knocking out a for-loop.
// Create some matrix A
A = zeros(8,8)
//initialize the array of indices
index = [];
// Get the dimensions of A
rows = size(A,1);
cols = size(A,2);
x = 0;
for i=1:length(A)
if(A(i)==x)
// Append it to list using $ (last index) + 1
index($+1) = i;
end
end
Without for-loop
If you just need the values that adhere to a certain condition you could also do something like this
values = A(A==x);
Be carefull when comparing doubles, these are not always (un)equal when you expect.
Coming to Scala from R (complete newbie).
Say I have two lists:
val index = List(0,0,1,0,1)
val a = List(1,2,3,4,5)
Then index can define a natural map from a to b: List[List[Int]]:
1 -> b(0)
2 -> b(0)
3 -> b(1)
4 -> b(0)
5 -> b(1)
So that:
b = List(List(1,2,4), List(3,5))
In general, given index and a, what is the most natural way to create b in Scala?
e.g. in R I could for example write:
run_map <- function(index, a) {
map <- function(data, i) {
data[[i]] <- a[which(index == i)]
data
}
Reduce(map, unique(index), list())
}
Cheers for any help!
If you want one list to contain the index and the other list to contain the values then you would zip them together:
val myMap = (a zip b).toMap
where a contains the index and b the values.
However, if there's duplicate indexes then you would want to do the following:
for{
(i, list) <- (a zip b) groupBy (_._1)
} yield (i, list map (_._2))
wherein you're zipping, grouping by the index and then mapping over the values in the list. That created list contains both the index and value as a tuple.
0) Given:
val index = List(0,0,1,0,1)
val a = List(1,2,3,4,5)
Here is an "iterative" way to arrive at the solution:
1) "Zip" 2 lists together to produce a list of pairs:
index.zip(a)
result:
List[(Int, Int)] = List((0,1), (0,2), (1,3), (0,4), (1,5))
2) Group by first element of the pair in the list.
index.zip(a).groupBy(_._1)
result:
Map[Int,List[(Int, Int)]] = Map(1 -> List((1,3), (1,5)), 0 -> List((0,1), (0,2), (0,4)))
3) Remove redundant index by projecting only second element from each pair in the list v:
index.zip(a).groupBy(_._1).map{ case (i, v) => (i, v.map(_._2)) }
result:
Map[Int,List[Int]] = Map(1 -> List(3, 5), 0 -> List(1, 2, 4))