Over a million developers have joined DZone.

Neo4j & Cypher: Flatten a Collection

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

Every now and then in Cypher land we’ll end up with a collection of arrays, often created via the COLLECT function, that we want to squash down into one array.

For example let’s say we have the following array of arrays…

$ RETURN [[1,2,3], [4,5,6], [7,8,9]] AS result;
==> +---------------------------+
==> | result                    |
==> +---------------------------+
==> | [[1,2,3],[4,5,6],[7,8,9]] |
==> +---------------------------+
==> 1 row

…and we want to return the array [1,2,3,4,5,6,7,8,9].

Many programming languages have a ‘flatten’ function and although cypher doesn’t we can make our own by using the REDUCE function:

$ WITH  [[1,2,3], [4,5,6], [7,8,9]] AS result 
  RETURN REDUCE(output = [], r IN result | output + r) AS flat;
==> +---------------------+
==> | flat                |
==> +---------------------+
==> | [1,2,3,4,5,6,7,8,9] |
==> +---------------------+
==> 1 row

Here we’re passing the array ‘output’ over the collection and adding the individual arrays ([1,2,3], [4,5,6] and [7,8,9]) to that array as we iterate over the collection.

If we’re working with numbers in Neo4j 2.0.1 we’ll get this type exception with this version of the code:

==> SyntaxException: Type mismatch: expected Any, Collection<Any> or Collection<Collection<Any>> but was Integer (line 1, column 148)

We can easily work around that by coercing the type of ‘output’ like so:

WITH  [[1,2,3], [4,5,6], [7,8,9]] AS result 
RETURN REDUCE(output = range(0,-1), r IN result | output + r);

Of course this is quite a simple example but we can handle more complicated scenarios as well by using nested calls to REDUCE. For example let’s say we wanted to completely flatten this array:

$ RETURN [[1,2,3], [4], [5, [6, 7]], [8,9]] AS result;
==> +-------------------------------+
==> | result                        |
==> +-------------------------------+
==> | [[1,2,3],[4],[5,[6,7]],[8,9]] |
==> +-------------------------------+
==> 1 row

We could write the following cypher code:

$ WITH  [[1,2,3], [4], [5, [6, 7]], [8,9]] AS result 
  RETURN REDUCE(output = [], r IN result | output + REDUCE(innerOutput = [], innerR in r | innerOutput + innerR)) AS flat;
==> +---------------------+
==> | flat                |
==> +---------------------+
==> | [1,2,3,4,5,6,7,8,9] |
==> +---------------------+
==> 1 row

Here we have an outer REDUCE function which iterates over [1,2,3], [4], [5, [6,7]] and [8,9] and then an inner REDUCE function which iterates over those individual arrays.

If we had more nesting then we could just introduce another level of nesting!

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}