Train explosion: Trying to iterate over a list to convert it into a linked list of nodes

I want to create a locomotive, and then add to it three train cars in succession where the first car is connected to the locomotive, the second car is connected to the first car, and the third car is connected to the second car. Below is my attempt, but it literally explodes.

CREATE (loco:Locomotive)
WITH ['car1', 'car2','car3'] AS carNames
UNWIND carNames AS carName
  MATCH (loco)-[:PULLS*0..2]->(last) WHERE NOT (last)-[:PULLS]->()
  MERGE (last)-[:PULLS]->(:Car {name:carName})

This is where list being first class element in Cypher really helps.

Try this query

CREATE (loco:Locomotive)
WITH loco, ['car1', 'car2','car3'] as list
MERGE (loco)-[:PULLS]->(:Car {name:list[0]})
WITH list, list[1..] as nextList
UNWIND range(0,size(nextList)-1,1) as index 
WITH list[index] as first, nextList[index] as second 
MERGE (c1:Car {name:first})
MERGE (c2:Car {name:second})
MERGE (c1)-[:PULLS]->(c2)
1 Like
Step 1: Create Cars nodes:

merge  (a1:Cars {name: 'car1'})
merge  (a2:Cars {name: 'car2'})
merge  (a3:Cars {name: 'car3'})

Step 2: Link the Cars

match (d:Cars)
with d order by id(d) ASC
with collect(d) as c2
CALL apoc.nodes.link(c2, 'PULLS')
return c2

Step 3: Link the engine to cars

match (d:Cars)
with d order by id(d) ASC
with collect(id(d)) as c2
unwind c2 as c3
with min(c3) as mn
match (f:Cars) where id(f) = mn
with f
merge (loco:Locomotive)
merge (loco)-[:CARS]->(f)
return loco, f

Result:

1 Like

This is a great solution too. Easier for me to understand and test intermediate values. Thank you.

You were so fast. I live in Norway. I wrote the question and went to sleep. By the time I looked I had two working solutions. This community is great, which is you guys.

1 Like