admin管理员组

文章数量:1405510

I have a kids object that looks like the following:

const kids = {
    name: 'john',
    extra: {
        city: 'London',
        hobbies: [
            {
                id: 'football',
                team: 'ABC',
            },
            {
                id: 'basketball',
                team: 'DEF',
            },
        ],
    },
};

and i have the following object that contains all sports and extra info for each.

const sports = [
    {
        name: 'volleyball',
        coach: 'tom',
    },
    {
        name: 'waterpolo',
        coach: 'jack',
    },
    {
        name: 'swimming',
        coach: 'kate',
    },
    {
        name: 'football',
        coach: 'sara',
    },
];

I want to get the list of all ids in the hobbies array and go through each of the sports items in the sports array, and found, add an extra field to that object available and give a value of true, so the result will look like:

const result = [
    {
        name: 'volleyball',
        coach: 'tom',
    },
    {
        name: 'waterpolo',
        coach: 'jack',
    },
    {
        name: 'swimming',
        coach: 'kate',
    },
    {
        name: 'football',
        coach: 'sara',
        available: true
    },
];

by the way, here is my attempt:

const result = kids.extra.hobbies.map(a => a.id);
for (var key in sports) {
    console.log(sports[key].name);
    const foundIndex = result.indexOf(sports[key].name);
    if ( foundIndex > -1) {
      sports[key].available = true;
    }
}
console.log(sports)

but this is too long... i am looking one liner looking code and robust logic.

I have a kids object that looks like the following:

const kids = {
    name: 'john',
    extra: {
        city: 'London',
        hobbies: [
            {
                id: 'football',
                team: 'ABC',
            },
            {
                id: 'basketball',
                team: 'DEF',
            },
        ],
    },
};

and i have the following object that contains all sports and extra info for each.

const sports = [
    {
        name: 'volleyball',
        coach: 'tom',
    },
    {
        name: 'waterpolo',
        coach: 'jack',
    },
    {
        name: 'swimming',
        coach: 'kate',
    },
    {
        name: 'football',
        coach: 'sara',
    },
];

I want to get the list of all ids in the hobbies array and go through each of the sports items in the sports array, and found, add an extra field to that object available and give a value of true, so the result will look like:

const result = [
    {
        name: 'volleyball',
        coach: 'tom',
    },
    {
        name: 'waterpolo',
        coach: 'jack',
    },
    {
        name: 'swimming',
        coach: 'kate',
    },
    {
        name: 'football',
        coach: 'sara',
        available: true
    },
];

by the way, here is my attempt:

const result = kids.extra.hobbies.map(a => a.id);
for (var key in sports) {
    console.log(sports[key].name);
    const foundIndex = result.indexOf(sports[key].name);
    if ( foundIndex > -1) {
      sports[key].available = true;
    }
}
console.log(sports)

but this is too long... i am looking one liner looking code and robust logic.

Share Improve this question edited May 13, 2018 at 23:35 moaningalways asked May 13, 2018 at 23:28 moaningalwaysmoaningalways 4611 gold badge10 silver badges21 bronze badges 1
  • Just a sidenote, why are these arrays? Why not use objects, if the ids are unique? – Matt Way Commented May 13, 2018 at 23:38
Add a ment  | 

3 Answers 3

Reset to default 2

This can be done many ways; however, an easy was is to divide the problem into two steps:

We can first flatten the kid's hobbies into an array by using the Array.map() function:

const hobbies = kids.extra.hobbies.map(hobby => hobby.id);

Then, we can iterate through the sports array and add an active property to any object which is present in the new hobbies array:

const result = sports.map(sport => {
  if (hobbies.indexOf(sport.name) !== -1) {
    sport.available = true;
  }

  return sport;
})

Complete Solution

const kids = {
  name: 'john',
  extra: {
    city: 'London',
    hobbies: [{
        id: 'football',
        team: 'ABC',
      },
      {
        id: 'basketball',
        team: 'DEF',
      },
    ],
  },
};

const sports = [{
    name: 'volleyball',
    coach: 'tom',
  },
  {
    name: 'waterpolo',
    coach: 'jack',
  },
  {
    name: 'swimming',
    coach: 'kate',
  },
  {
    name: 'football',
    coach: 'sara',
  },
];

const hobbies = kids.extra.hobbies.map(hobby => hobby.id);


const result = sports.map(sport => {
  if (hobbies.indexOf(sport.name) !== -1) {
    sport.available = true;
  }

  return sport;
})

console.log(result);

Firstly, I would change my data structures to objects. Any time you have a list of things with unique ids, objects will make your life much easier than arrays. With that in mind, if you must use arrays, you could do the following:

const hobbies = kids.extra.hobbies
sports.forEach(s => s.available = hobbies.some(h => h.id === s.name))

Note that this mutates the original sports object (change to map for new), and also adds false/true instead of just true.

Build an array of the found sports first, then map while checking to see if the sports object's name is in it:

const kids = {name:'john',extra:{city:'London',hobbies:[{id:'football',team:'ABC',},{id:'basketball',team:'DEF',},],},}
const sports = [{name:'volleyball',coach:'tom',},{name:'waterpolo',coach:'jack',},{name:'swimming',coach:'kate',},{name:'football',coach:'sara',},];
const sportsInHobbies = kids.extra.hobbies.map(({ id }) => id);
const result = sports.map((sportObj) => {
  const available = sportsInHobbies.includes(sportObj.name);
  return available ? {...sportObj, available } : { ...sportObj };
});
console.log(result);

本文标签: javascript map two nested arrays and modify the existing by lookupsStack Overflow