0

Given the following structure:

const data = {
  "show": "Family Guy",
  "characters": [
      [{name: 'Peter', age: 40, city: 'Quahog'}],
      [{name: 'Louis', age: 30}],
      [{name: 'Chris', age: 16}],
      [{name: 'Stewie', age: 1}]
    ]
 }

How can we add to each character the key/value pair of city: 'Quahog' so the output looks as follows:

const item = {
  "show": "Family Guy",
  "characters": [
      [{name: 'Peter', age: 40, city: 'Quahog'}],
      [{name: 'Louis', age: 30, city: 'Quahog'}], // city added
      [{name: 'Chris', age: 16, city: 'Quahog'}], // city added
      [{name: 'Stewie', age: 1, city: 'Quahog'}]  // city added
    ]
 }

We tried using:

let city = data.characters.[0][0].city;
costs = _.map(items, (itemArray) => {
            items = _.map(itemArray, (item) => {
              if(!item.city) {
                item.city = city;
              }
        });

But it's not working as intended and we can't get the desired output. Any idea how to accomplish this?

5 Answers 5

2

Not sure about the reason for having these single item arrays but this solution will do the work (I'll recommend you take a look at the process that creates this data format which is a little weird)

const data = {
  "show": "Family Guy",
  "characters": [
      [{name: 'Peter', age: 40, city: 'Quahog'}],
      [{name: 'Louis', age: 30}],
      [{name: 'Chris', age: 16}],
      [{name: 'Stewie', age: 1}]
    ]
 }
 
 const city = data.characters.find(characters => characters.find(character => character.city))[0].city

const dataWithCities = {
 ...data,
 characters: data.characters.map(characters => characters.map(character => character.city ? character : {...character, city}))
 }
 
 console.log(dataWithCities)

Sign up to request clarification or add additional context in comments.

Comments

1

Here is another way of doing it with .reduce():

const data = {
  "show": "Family Guy",
  "characters": [
  [{name: 'Peter', age: 40, city: 'Quahog'}],
  [{name: 'Louis', age: 30}],
  [{name: 'Chris', age: 16}],
  [{name: 'Stewie', age: 1}]
]
 };

data.characters.reduce((a,c)=>
 (c[0].city=a[0].city,a));

console.log(data);

When using .reduce() without a second argument it will pick up the first array element as the initial value which is then used as a template to copy the .city property to all the other elements. The actual return value of the .reduce() method is discarded but the input array itself (data) is modified in the process and is then shown in the console.log() expression.

3 Comments

Thank you so much, this is the shortest and sweetest way to do it. In your desc, did you mean with a second argument? Also, in the return does the ,a part just write the modified result back to a, or does it do something else? Thanks again
Well, the callback function is the first argument of the .reduce() method (the callback function in turn has two arguments). But the missing second argument to the .reduce() method would have been a starting value, which is missing on purpose here.
The ,a part in the callback makes sure that the accumulator (in this case: the first array element) is handed along to the next iteration. Without it the .reduce() call would fail.
0

try this one

let city = data.characters.[0][0].city;
let newdata = [];
data.characters.map(items, (itemArray) => {
        items = _.map(itemArray, (item) => {
          if(item.city === undefined) {
              newdata.push({...item , city});
          } else { 
           newdata.push({...item});
           }

    })
    costs = {...newdata}

1 Comment

Please add supporting details to your answer to improve it.
0

You can do this without lodash

const data = {
  "show": "Family Guy",
  "characters": [
      [{name: 'Peter', age: 40, city: 'Quahog'}],
      [{name: 'Louis', age: 30}],
      [{name: 'Chris', age: 16}],
      [{name: 'Stewie', age: 1}]
    ]
 }

const chars = data.characters.map((x)=>{

    return {...x[0] , city : x[0].city ? x[0].city : city} 
})

const items = {...data , characters : chars};

1 Comment

hmm this doesn't wrap each character in an array, it's just a group of object
0
const { city } = data.characters.find(([item]) => !!item.city?.length)[0];

const newData = {
    ...data,
    characters: data.characters.map(([char]) => [{ ...char, city }])
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.