-1

I have a Datasource which contains a nested array of objects. I have been able to select key value pair, and now I want to add those values to the top level of the object, i.e outside the nested object.

Initial array:

 data= [
  {
    "flowId": 7079,
    "flowName": "jackson-demo",
    "version": 1,
    "CreatedDate": "2020-04-02",
    "UpdateDate": "",
    "LastRunDate": "2020-04-02",
    "active": false,

"properties": [
  {
    "id": 7080,
    "key": "country",
    "value": "in",
    "category": "General"
  },
  {
    "id": 7081,
    "key": "source",
    "value": "hive",
    "category": "General"
  }
  ]

  },
  {

"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,

"properties": [
  {
    "id": 7080,
    "key": "country",
    "value": "au",
    "category": "General"
  },
  {
    "id": 7081,
    "key": "source",
    "value": "aws",
    "category": "General"
  }
  ]

} ]

Using the below code I am able to get the key value pair:

 for (var i = 0; i < data.length; i++) {
  data[i].properties.forEach((arrayItem, i) => {
    if (arrayItem.key === 'country') {
      console.log('Key: ' + arrayItem.key + ' ' + 'Value: ' + arrayItem.value);
    }
  });
}

Output of Code:

Key: country Value: au 
Key: country Value: in 

How do I push these values back in the array so that my new array looks like this:

data= [
  {
    "flowId": 7079,
    "flowName": "jackson-demo",
    "version": 1,
    "CreatedDate": "2020-04-02",
    "UpdateDate": "",
    "LastRunDate": "2020-04-02",
    "active": false,
    "country": "in"

"properties": [
  {
    "id": 7080,
    "key": "country",
    "value": "in",
    "category": "General"
  },
  {
    "id": 7081,
    "key": "source",
    "value": "hive",
    "category": "General"
  }
  ]

  },
  {

"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"country":"au"

"properties": [
  {
    "id": 7080,
    "key": "country",
    "value": "au",
    "category": "General"
  },
  {
    "id": 7081,
    "key": "source",
    "value": "aws",
    "category": "General"
  }
  ]

} ]
trincot
  • 317,000
  • 35
  • 244
  • 286
Cpt Kitkat
  • 1,392
  • 4
  • 31
  • 50
  • 1
    [There is no such thing as a JSON object](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/). – Heretic Monkey Apr 03 '20 at 14:45
  • You already keep track of the index of the object, inside your loop. Why not just use that index to push it back on the right level – Erik van de Ven Apr 03 '20 at 14:45
  • Removed the `json` tag and "JSON" from question. Please read the description before adding that tag. – trincot Apr 03 '20 at 14:48
  • Does this answer your question? [How can I add a key/value pair to a JavaScript object?](https://stackoverflow.com/questions/1168807/how-can-i-add-a-key-value-pair-to-a-javascript-object) – mikemaccana Apr 03 '20 at 14:50

3 Answers3

0

Try update data[i] using spread operator :

 for (var i = 0; i < data.length; i++) {
  data[i].properties.forEach((arrayItem, i) => {
    if (arrayItem.key === 'country') {
      data[i] = { ...data[i] , arrayItem }
    }
  });
}
0

You could use Object.fromEntries:

for (let item of data) {
  Object.assign(item,
    Object.fromEntries(item.properties.map(({key, value}) => [key, value]))
  );
}

In case you only want to add some of these pairs, you can chain a .filter to the .map result, or if you just need one ("country"), use a more basic programming pattern:

for (let item of data) {
  item.country = item.properties.find(({key}) => key == "country").value;
}
trincot
  • 317,000
  • 35
  • 244
  • 286
0

This creates a new array with copies of your objects having an additional country property if it's found:

const addCountry = data => data .map (({properties, ...rest}) => {
  const country = properties .find (({key}) => key == 'country')
  return {
    ... rest,
    ... (country ? {country: country .value} : {}),
    properties
  }
})


const data = [{flowId: 7079, flowName: "jackson-demo", version: 1, CreatedDate: "2020-04-02", UpdateDate: "", LastRunDate: "2020-04-02", active: false, properties: [{id: 7080, key: "country", value: "in", category: "General"}, {id: 7081, key: "source", value: "hive", category: "General"}]}, {flowId: 7079, flowName: "jackson-demo", version: 1, CreatedDate: "2020-04-02", UpdateDate: "", LastRunDate: "2020-04-02", active: false, properties: [{id: 7080, key: "country", value: "au", category: "General"}, {id: 7081, key: "source", value: "aws", category: "General"}]}];

console .log (
  addCountry (data)
)
.as-console-wrapper {min-height: 100% !important; top: 0}

If the only use of properties in the output is already satisfied by this extraction, then you could skip the properties line in the output and have more lightweight versions for further processing.

We could, of course, choose to mutate the original data, but we're not barbarians, right?

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