How do I collect the items of a stream into a JSON array?

← JSON and Data Processing · Ref: Q1411

Pour the stream into the JSON - 'collect as JSON', or '>' into a JSON you already have. Pouring into JSON follows the target's shape: an unset or array target collects, an object target merges each streamed object in; anything else - a non-object into an object, or anything into a single value - is invalid, leaves the target unset, and later items do not revive it.

AN UNSET TARGET COLLECTS

An unset JSON has no shape yet, so it becomes an array of the items - objects included, and one item still gives an array of one:

  collected <- cat [JSON(1), JSON("two"), JSON("name", JSON("Ann"))] | collect as JSON
  stdout.println($collected)

AN ARRAY TARGET APPENDS EACH ITEM

Every streamed item becomes ONE element, so an array poured in is appended whole, not spread into its elements:

  numbers <- $$ [0]
  cat [JSON(1), $$ [2, 3]] > numbers
  stdout.println($numbers)

To spread an array's elements into another array, merge it instead: numbers :~: other appends its elements.

UNSET ITEMS ARE DROPPED

Like every '|' an unset item is dropped, and a JSON null counts as unset, so it is dropped too.

See Q1412 for pouring objects into an object. See Q1413 for a target that ends up unset. See Q191 for pouring JSON into other types.

Example

defines module qa.jsonanddata.jsonpourcollects

  defines program

    JsonPourCollectsDemo()
      stdout <- Stdout()

      //An unset target has no shape yet: it collects the items into an array, objects too
      collected <- cat [JSON(1), JSON("two"), JSON("name", JSON("Ann"))] | collect as JSON
      stdout.println(`collected: ${collected}`)

      //One item still gives an array of one
      single <- JSON()
      cat [JSON(7)] > single
      stdout.println(`one item: ${single}`)

      //An array target appends each item as ONE element - the array [2, 3] is not spread
      numbers <- $$ [0]
      cat [JSON(1), $$ [2, 3]] > numbers
      stdout.println(`appended: ${numbers}`)

      //An unset item is dropped (so is a JSON null, which is unset)
      withUnset <- $$ [1]
      cat [JSON(), JSON(2)] > withUnset
      stdout.println(`unset dropped: ${withUnset}`)
Other ways to ask this
  • What does 'collect as JSON' give me?
  • What happens when I stream items into an empty JSON?
  • How do I append streamed items to an existing JSON array?
  • Does pouring an array into a JSON array spread its elements?

Coming from another language?

Java: Jackson ArrayNode.add() in a loop, or stream().collect() into a List and then valueToTree. Python: json.dumps([item for item in items]). JavaScript: items.map(...) then JSON.stringify. EK9: cat items | collect as JSON gathers JSON items into an array, and '>' appends them to an existing array, each item one element.

Keywords: append, stream, gather, pour, collect, array, pipe, unset, json