0

I have this datas structure:

{
  "fieldNodes": [
    {
      "selectionSet": {
        "selections": [
          {
            "name": {
              "value": "id"
            }
          },
          {
            "name": {
              "value": "phone"
            }
          },
          {
            "name": {
              "value": "address"
            },
            "selectionSet": {
              "selections": [
                {
                  "name": {
                    "value": "street"
                  }
                },
                {
                  "name": {
                    "value": "city"
                  }
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

I need to go over the fieldNodes array in recursion and create an array of strings of their value (name.value).

The nested values will be represented by a dot ("address.city").

The results for this example will be: ["id", "phone", "address. street", "address.city"].

I'm assuming that I have one object in the fieldNodes array.

Can someone please help me how the code should look like in NodeJS?

mkjh
  • 1,634
  • 13
  • 25
maya dahan
  • 205
  • 3
  • 15
  • I try the solution from this and it works. https://stackoverflow.com/questions/54857222/find-all-values-by-specific-key-in-a-deep-nested-object – ikhvjs Jun 03 '21 at 10:32

3 Answers3

1

Once you descend to the selectionSort level, it's a fairly straightforward recursion. Here we wrap that recursive call into one that (flat)maps over the fieldNodes objects. Since you expect only one, it doesn't matter whether we map or flatMap here, and this result is simpler. But if you might have more than one, and you want them grouped, you might replace fieldNodes .flatMap (...) with fieldNodes .map (...)

const processSelectionSet = ({selectionSet: {selections = []}}) =>
  selections.flatMap (
    ({name: {value}, selectionSet}) => selectionSet 
      ? processSelectionSet ({selectionSet}) .map (name => `${value}.${name}`)
      : value
  )

const extract = ({fieldNodes = []}) => 
  fieldNodes .flatMap (processSelectionSet)

const input = {fieldNodes: [{selectionSet: {selections: [{name: {value: "id"}}, {name: {value: "phone"}}, {name: {value: "address"}, selectionSet: {selections: [{name: {value: "street"}}, {name: {value: "city"}}]}}]}}]}

console .log (extract (input))

The main function, processSelectionSort simply flatmaps over the selections, capturing the name/value reporting it back if there is no selectionSort child node or merging it with the results of the recursive call to that child node if it exists.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
0

Try this recursive function that I made:

var obj = {
  "fieldNodes": [{
    "selectionSet": {
      "selections": [{
          "name": {
            "value": "id"
          }
        },
        {
          "name": {
            "value": "phone"
          }
        },
        {
          "name": {
            "value": "address"
          },
          "selectionSet": {
            "selections": [{
                "name": {
                  "value": "street"
                }
              },
              {
                "name": {
                  "value": "city"
                }
              }
            ]
          }
        }
      ]
    }
  }]
};

function flatten(obj) {
  if (!obj.selectionSet) {
    if (obj.name) return [obj.name.value];
    return [];
  }
    
  var list = obj.selectionSet.selections.map(flatten).flat();
  if (!obj.name) return list;
  return list.map(item => obj.name.value + "." + item);
}

var list = obj.fieldNodes.map(flatten).flat();
console.log(list);
Dhaval Darji
  • 513
  • 5
  • 19
Gpack
  • 1,878
  • 3
  • 18
  • 45
0

You can use a recursive generator function:

var data = {'fieldNodes': [{'selectionSet': {'selections': [{'name': {'value': 'id'}}, {'name': {'value': 'phone'}}, {'name': {'value': 'address'}, 'selectionSet': {'selections': [{'name': {'value': 'street'}}, {'name': {'value': 'city'}}]}}]}}]}
function* flatten(d, c = []){
    for (var i of d){
       if ("selectionSet" in i){
           yield* flatten(i.selectionSet.selections, 'name' in i ? [...c, i.name.value] : c)
       }
       else{
          yield [...c, i.name.value]
       }
    }
}
var result = Array.from(flatten(data.fieldNodes)).map(x => x.join('.'));
console.log(result)
Ajax1234
  • 69,937
  • 8
  • 61
  • 102