用另一个数组对对象数组进行映射获取不同的键值对。

6

我不确定为什么会遇到这样的困难,但我有一个id数组,我正在尝试使用它来映射对象数组以查找相应的id,但返回来自不同键的值。

例如: arr=[13, 1, 16]

arrObj= [{
          id: 1,
          name: "cat"
         }, {
          id: 10,
          name: "tiger", 
         }, {
          id: 3,
          name: "dog", 
         }, {
          id: 16,
          name: "bear", 
         }, {
          id: 8,
          name: "fish", 
         }, {
          id: 13,
          name: "goat", 
         }]

我有一个嵌套的映射函数,它可以做到这一点,但对于没有相应ID的对象返回未定义。 我可以从返回的数组中过滤掉未定义的内容,但似乎有更清晰/更有效的方法来实现这一点。

有什么最清晰的方法可以实现这个目标呢?

我希望它返回:["goat", "cat", "bear"]

5个回答

6
你可以使用 Array#map 方法,并结合 Array#find 方法查找相应的对象,然后将 name 作为返回值。

var arr = [13, 1, 16],
    arrObj = [{ id: 1, name: "cat" }, { id: 10, name: "tiger" }, { id: 3, name: "dog" }, { id: 16, name: "bear" }, { id: 8, name: "fish" }, { id: 13, name: "goat" }],
    result = arr.map(id => arrObj.find(o => o.id === id).name);

console.log(result);

对于大量的数据,你可以使用Map,通过映射键值对来构建它,然后再映射map的结果。

var arr = [13, 1, 16],
    arrObj = [{ id: 1, name: "cat" }, { id: 10, name: "tiger" }, { id: 3, name: "dog" }, { id: 16, name: "bear" }, { id: 8, name: "fish" }, { id: 13, name: "goat" }],
    result = arr.map(
        Map.prototype.get,
        new Map(arrObj.map(({ id, name }) => [id, name]))
    );

console.log(result);


太棒了!谢谢,这正是我在寻找的! - CharStar
如果可以避免,您可能不想嵌套循环,在这种情况下,您绝对可以避免。通过一次转换对象数组,您可以获得一个可用于查找值的对象。因此,没有必要在每次迭代中运行“find”,这根本不高效。https://dev59.com/Hazka4cB1Zd3GeqP7V-2#50994305 - Mohammed Siddeeq
@MohammedSiddeeq,你是对的,一个对象也可以工作。对于第二种方法,我包含了一个映射表,这应该比继续使用“find”更快。 - Nina Scholz

4

Try this:

var arr=[13, 1, 16];
var arrObj= [{
          id: 1,
          name: "cat"
         }, {
          id: 10,
          name: "tiger", 
         }, {
          id: 3,
          name: "dog", 
         }, {
          id: 16,
          name: "bear", 
         }, {
          id: 8,
          name: "fish", 
         }, {
          id: 13,
          name: "goat", 
         }];

var result = arr.map(id => arrObj.find(x => x.id == id)).map(x => x.name)
console.log(result);
// ["goat", "cat", "bear"]

.map()(来自MDN web docs):

该方法会对调用它的数组中的每个元素执行提供的函数,并使用函数返回值创建一个新数组。

.find()(来自MDN web docs):

该方法返回数组中满足提供的测试函数的第一个元素的。否则,将返回undefined


请注意,循环是双重的,但我将过滤器和映射分开以更清晰地表达,您可以在第一个循环中完成。 - user2693928

1

已经有很多好的答案了,但是我觉得有必要推动新的语法,因为从长远来看它更容易处理。

const getNamesBasedOnIds = (arr, listOfIds) => {
   return arr.reduce(((sum, element) => 
      [...sum, ...(listOfIds.includes(element.id) ? [element.name] : [])]),
   []);
}

const animals = getNamesBasedOnIds(arrObj, [13,1,16]);

使用Array.filter,然后使用Array.map需要您运行Array两次。
使用Array.reduce,如果listOfIds中存在elements,则可以将其添加到sum中,然后在运行一次arrObj后即可得出结果。 [...sum, ...(listOfIds.includes(element.id) ? [element.name] : [])]非常慢,但更多地展示了使用扩展运算符的用法。
以上等同于 sum.concat(listOfIds.includes(element.id) ? element.name : []) 最快的方法是使用Array.push
if(listOfIds.includes(element.id)){
   sum.push(element.name);
}
return sum;

1
正确的方法是不要嵌套任何循环:
  1. 将对象数组缩减为“id-value”映射的地图 idValueMap
  2. 使用 idValueMap 映射通过 'ids' 数组进行遍历,以在常数时间内获取每个 id 的相应值。
思路 了解最大的问题就是数据本身。不要让不足的数据类型或结构强制你拥有一个糟糕的解决方案/代码。转换数据使其符合您的需求,以便您可以创建适当的解决方案。
基本上,想象一下 objArr 如果只是一个 Map,你可以用它来查找 id 的值......那么解决方案就很简单了。所以让我们实现它,然后其他问题就迎刃而解了。数据数据数据是我总是说的 :) 经验法则:如果可能的话,永远不要在循环内运行循环。另外,filter、find、map、indexOf……都是内部循环,除非绝对必要,否则不要嵌套使用。 这种解决方案是迄今为止最高效的。这样你就不会运行O(n^2)(非常糟糕),而是运行O(n)(非常好)。

    const idArr = [ 13, 1, 16 ];
    const objArr= [
      {
        id: 1,
        name: "cat"
      }, 
      {
        id: 10,
        name: "tiger", 
      }, 
      {
        id: 3,
        name: "dog", 
      }, 
      {
        id: 16,
        name: "bear", 
      }, 
      {
        id: 8,
        name: "fish", 
      }, 
      {
        id: 13,
        name: "goat", 
      }
    ];
    
    const idValueMap = objArr.reduce((acc, { id, name }) => ({ ...acc, [id]: name }), {});
    let output = idArr.map((id) => idValueMap[id]);
    console.log(output);


0
你可以先使用 .filter 进行筛选,然后再使用 .map 输出所需的属性。
这里。

var arr = [13, 1, 16],
    arrObj = [{
        id: 1,
        name: "cat"
    }, {
        id: 10,
        name: "tiger",
    }, {
        id: 3,
        name: "dog",
    }, {
        id: 16,
        name: "bear",
    }, {
        id: 8,
        name: "fish",
    }, {
        id: 13,
        name: "goat",
    }];

var res = arrObj.filter(o => arr.indexOf(o.id) >= 0);

console.log(res.map(o => o['name']))


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