【问题标题】:Filtering using two array of objects using JavaScript使用 JavaScript 使用两个对象数组进行过滤
【发布时间】:2020-04-19 01:45:00
【问题描述】:

我有一个如图所示的数组:

var arrOne = [{id: 3},{id: 8},{id: 12}];

还有一个数组如图:

var arrTwo = [
  {id: 1, val: 'Adam'},
  {id: 3, val: 'Bailey'},
  {id: 8, val: 'Cathy'},
  {id: 12, val: 'David'},
  {id: 15, val: 'Earl'}
];

我想基于 arrOne 迭代 arrTwo,并从 arrTwo 中获取 val 值。 所以结果应该是:

var result = ['Bailey', 'cathy', 'David'];

尝试将 .map 与 .filter 连接:

arrOne.map(arOne => arrTwo.filter(artwo => {
    if(arOne.id === artwo.id) {
      return artwo.val
    } else {
      return false;
    }
}));

但它给了我一切,它是假的,它在那里增加了假,这是我不想要的。 任何我出错的想法都将不胜感激。

根据norbitrial的回答进行编辑:

const arrOne = [{id: 3},{id: 8},{id: 12}];
const arrTwo = [
                 {id: 1, val: 'Adam'}, 
                 {id: 3, val: 'Bailey'}, 
                 {id: 8,    val: 'Cathy'}, 
                 {id: 12, val: 'David'}, 
                 {id: 15, val: 'Earl'}
               ];

const result = arrOne.map(({id}) => arrTwo.find(e => {
  const someCond = someConditionaEval();
  if(someCond && e.id === id) {
     return e;
  } else {
     return false;
  }
}).val); //this breaks

【问题讨论】:

  • arrOne.map(o => arrTwo.find(t => t.id === o.id));

标签: javascript arrays filtering


【解决方案1】:

使用.map().find() 组合:

const arrOne = [{id: 3},{id: 8},{id: 12}];
const arrTwo = [{id: 1, val: 'Adam'}, {id: 3, val: 'Bailey'}, {id: 8, val: 'Cathy'}, {id: 12, val: 'David'}, {id: 15, val: 'Earl'}];

const result = arrOne.map(({id}) => arrTwo.find(e => e.id === id).val);

console.log(result);

我希望这会有所帮助!

【讨论】:

  • 感谢您的回复,如果我必须在这里添加一些额外的检查?: if(e.id === id && someCheck1 && someCheck2) {return e} else {return false}跨度>
  • @MichaelPhilips 视情况而定,但很可能您可以将其包含在 .find() 条件中。
  • 我的问题是我必须在'e => e.id === id'中添加一些if()条件,如果我这样做,我到底该怎么做.val ?因为要在里面添加 if 我必须添加括号,例如 .find(e => { const someCond = someCondEvaluator(); if(someCond && e.id === id) { return e } else { return false } } .val //.val 在这里不起作用
  • @MichaelPhilips 这是我在回答中所做的简短版本,但您可以像下面的功能块一样使用:.find(e => { if (e.id === id) { /* your code */ } else { /* your code */ } }) 但您肯定需要为.find() 返回布尔类型。我希望澄清!
【解决方案2】:

您可以在arrTwo 上使用.filter() 方法,然后使用.includes() 方法从arrTwo 中获取过滤后的对象,最后使用.map() 仅从每个过滤后的对象中获取val 属性值,例如:

var arrOne = [{id: 3},{id: 8},{id: 12}];
var arrTwo = [{id:1,val:"Adam"},{id:3,val:"Bailey"},{id:8,val:"Cathy"},{id:12,val:"David"},{id:15,val:"Earl"}];
             
var result = arrTwo.filter(a => arrOne.map(o=>o.id).includes(a.id)).map(o=>o.val)
console.log( result )

【讨论】:

    【解决方案3】:

    您可以获取具有值的对象,然后映射所需的值。

    var arrOne = [{ id: 3 }, { id: 8 }, { id: 12 }],
        arrTwo = [{ id: 1, val: 'Adam' }, { id: 3, val: 'Bailey' }, { id: 8, val: 'Cathy' }, { id: 12, val: 'David' }, { id: 15, val: 'Earl' }],
        values = arrTwo.reduce((r, { id, val }) => (r[id] = val, r), {}),
        result = arrOne.map(({ id }) => values[id]);
    
    console.log(result);

    【讨论】:

      【解决方案4】:

      通过idarrTwo创建val的映射,然后映射arrOne,并使用id从映射中提取val

      为什么我更喜欢创建地图/字典(对象)而不是使用 Array.map()Array.find()

      由于复杂性 - 例如Array.map()Array.find() 是 O(n * m),而创建 Map 然后使用 Array.map() 获取值是 O(n + m)。但是,如果您有两个小数组,这实际上不会影响实际性能。

      const arrOne = [{id: 3},{id: 8},{id: 12}];
      const arrTwo = [{id: 1, val: 'Adam'}, {id: 3, val: 'Bailey'}, {id: 8, val: 'Cathy'}, {id: 12, val: 'David'}, {id: 15, val: 'Earl'}];
      
      const valById = new Map(arrTwo.map(({ id, val }) => [id, val]));
      
      const result = arrOne.map(o => valById.get(o.id));
      
      console.log(result);

      【讨论】:

        【解决方案5】:
        1. 从 arrTwo 构建一个对象以在一次迭代中收集 val。
        2. 在 arrOne 上使用 map 并从上面的对象中获取 val。

        const update = (arr1, arr2) => {
          const all = Object.fromEntries(arr2.map(({ id, val }) => [id, val]));
          return arr1.map(({ id }) => all[id]);
        };
        
        var arrOne = [{ id: 3 }, { id: 8 }, { id: 12 }];
        
        var arrTwo = [
          { id: 1, val: "Adam" },
          { id: 3, val: "Bailey" },
          { id: 8, val: "Cathy" },
          { id: 12, val: "David" },
          { id: 15, val: "Earl" }
        ];
        
        console.log(update(arrOne, arrTwo));

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-19
          • 2016-12-30
          • 1970-01-01
          相关资源
          最近更新 更多