JavaScript映射两个嵌套数组并通过查找修改现有数组

4

我有一个名为kids的对象,它看起来像下面这样:

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',
    },
];

我希望获取hobbies数组中所有id的列表,并遍历sports数组中的每个项目,如果发现,则为该对象添加一个额外的字段available并赋值为true,以便结果如下:
const result = [
    {
        name: 'volleyball',
        coach: 'tom',
    },
    {
        name: 'waterpolo',
        coach: 'jack',
    },
    {
        name: 'swimming',
        coach: 'kate',
    },
    {
        name: 'football',
        coach: 'sara',
        available: true
    },
];

顺便说一下,这是我的尝试:
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)

但是这太长了...我正在寻找一行代码和强大的逻辑。


只是一点小建议,如果这些id是唯一的,为什么要使用数组呢?为什么不使用对象呢? - Matt Way
3个回答

2

有多种方法可以实现这个,但是一种简单的方法是将问题分成两步:

我们可以先使用Array.map()函数将孩子的爱好展平成一个数组:

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

然后,我们可以遍历sports数组,并向任何存在于新的hobbies数组中的对象添加一个active属性:
const result = sports.map(sport => {
  if (hobbies.indexOf(sport.name) !== -1) {
    sport.available = true;
  }

  return sport;
})

完整解决方案


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);


2

首先,我会将我的数据结构改成对象。当你有包含唯一标识符的东西列表时,对象比数组更容易使用。如果必须使用数组,则可以执行以下操作:

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

请注意,这会改变原始的 sports 对象(如果需要新的,请使用 map 方法),并且添加了 false/true 而不仅仅是 true。

1
首先构建一个找到的运动数组,然后在检查运动对象名称是否在其中时使用map:

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);


1
我很喜欢你在上面对另一个答案进行迭代的评论,因为你的方法也是一样的。 - Matt Way

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接