【问题标题】:Retrieving item between two arrays of object with complex conditions在具有复杂条件的两个对象数组之间检索项目
【发布时间】:2021-03-03 15:46:15
【问题描述】:

我有两个对象列表:

let list1 = [{id: '1', status: 'use', comment: 'xxxx'}, {id: '2', status: 'ready', comment: 'yyyy'}, {id: '3', status: 'ready', comment: 'zzzz'}];
let list2 = [{uid: '1', elec: 60}, {uid: '2', elec: 60}, {uid: '10', elec: 60}, {uid: '3', elec: 40}];

我想要的是检索具有 elec > 50 且与 list1 的一个项目 id 相同的 uid 的 list2 对象,仅当 list1 的项目具有状态 ==“就绪”时。另外,我想将 list1 对象中的参数“comment”添加到此项。

在这个例子中,我的结果值为:{uid: '2',lect: 60, comment: 'yyyy'}。

我这样做了:

  let list1Filtered = list1.filter(itemList1 => itemList1.status == 'ready');
  let list2Filtered = list2.filter(itemList2 => itemList2.elec > 50);
  var result;

  for ( let  itemList1Filtered of list1Filtered ) {
    for ( let  itemList2Filtered of list2Filtered ) {
      if (!result && itemList1Filtered.id == itemList2Filtered.uid) {
        result = itemList2Filtered;
        result.comment = itemList1Filtered.comment;
      }
    }
  }
  
  return result;

我想知道是否有更优雅和/或更复杂的方式在 Javascript 中执行此操作。

【问题讨论】:

  • 如果不止一项符合条件怎么办?
  • 另外,您的> 60 表示示例中没有任何项目匹配。你需要>= 60
  • @GabrielePetrioli :应该选择第一个。我只在 if set 结果中使用了 !result 1 次。对于 60,你是对的,这是一个错字,我用> 50 修复了它。对此感到抱歉
  • 您可以直接在循环中的 if 语句中执行 return result;,而不是检查 !result

标签: javascript arrays typescript performance optimization


【解决方案1】:

您可以从 list1 收集想要的 cmets 并通过检查 elec 的值以及是否存在另一个列表中的项目来减少 list2。然后返回一个新对象。

这种方法只需要两个循环。

const
    list1 = [{ id: '1', status: 'use', comment: 'xxxx' }, { id: '2', status: 'ready', comment: 'yyyy' }, { id: '3', status: 'ready', comment: 'zzzz' }],
    list2 = [{ uid: '1', elec: 60 }, { uid: '2', elec: 60 }, { uid: '10', elec: 60 }, { uid: '3', elec: 40 }],
    l1 = list1.reduce((r, { id, status, comment }) => {
        if (status === 'ready') r[id] = { comment };
        return r;
    }, {}),
    result = list2.reduce((r, o) => {
        if (o.elec > 50 && o.uid in l1) r.push({ ...o, ...l1[o.uid]})
        return r;
    }, []);

console.log(result);

【讨论】:

    【解决方案2】:
    let result = {
        ...list2.filter(
        a => a.elec > 50 && a.uid === list1.filter(b => b.status === "ready")[0].id)[0],
        comments: list1.filter(b => b.status === "ready")[0].comment
    }
    
    

    【讨论】:

    • @Aion 我认为这是它可以得到的最短的,但它基本上也使用两个循环,就像你的解决方案一样,这已经可以了。
    【解决方案3】:

    试试这个:

    let list1 = [
      { id: '1', status: 'use', comment: 'xxxx' },
      { id: '2', status: 'ready', comment: 'yyyy' },
      { id: '3', status: 'ready', comment: 'zzzz' },
    ];
    let list2 = [
      { uid: '1', elec: 60 },
      { uid: '2', elec: 60 },
      { uid: '10', elec: 60 },
      { uid: '3', elec: 40 },
    ];
    
    let result = null;
    let itemFound;
    
    const filteredList = list2.filter((list2Item) => {
      if (!result) {
        itemFound =
          list2Item.elec > 50 &&
          list1.find(
            (list1Item) =>
              list2Item.uid === list1Item.id && list1Item.status === 'ready'
          );
        if (itemFound) {
          result = {
            uid: list2Item.uid,
            elect: list2Item.elec,
            comment: itemFound.comment,
          };
        }
      }
    });
    
    console.log(result);

    【讨论】:

      【解决方案4】:

      这应该可以完成工作:

      const list1 = [{
        id: '1',
        status: 'use',
        comment: 'xxxx'
      }, {
        id: '2',
        status: 'ready',
        comment: 'yyyy'
      }, {
        id: '3',
        status: 'ready',
        comment: 'zzzz'
      }];
      
      const list2 = [{
        uid: '1',
        elec: 60
      }, {
        uid: '2',
        elec: 60
      }, {
        uid: '10',
        elec: 60
      }, {
        uid: '3',
        elec: 40
      }];
      
      const filteredList = list2.filter(item => {
        const readyItemsList1 = list1.filter(item => item.status === 'ready').map(item => item.id);
        return item.elec > 50 && readyItemsList1.indexOf(item.uid) > -1
      }).map(item => {
        const comment = list1.find(it => it.id === item.uid).comment;
        item.comment = comment;
        return item;
      });
      
      console.log(filteredList);

      【讨论】:

      • 不添加评论。
      • 哎呀,对不起,我错过了要求中的那一点;我会立即修改。感谢您让我注意到它。
      【解决方案5】:
      you can restructure your data. List1 convert it in object. And now we can find solution in O(n).
      

      let list1 = [{
        id: '1',
        status: 'use',
        comment: 'xxxx'
      }, {
        id: '2',
        status: 'ready',
        comment: 'yyyy'
      }, {
        id: '3',
        status: 'ready',
        comment: 'zzzz'
      }];
      let list2 = [{
        uid: '1',
        elec: 60
      }, {
        uid: '2',
        elec: 60
      }, {
        uid: '10',
        elec: 60
      }, {
        uid: '3',
        elec: 40
      }];
      const itemList = {}
      list1.forEach(item => {
        if (item.status === 'ready') {
          itemList[item.id] = item.comment
        }
      });
      const result = list2.filter(item => itemList[item.uid] && item.elec > 50).map(item => {
        item['comment'] = itemList[item.uid]
        return item
      })
      console.log(result)

      【讨论】:

        【解决方案6】:

        filtermap 会帮助你。

        filter 可以选择符合某些条件的项目,map 让您更改要选择的数据。

        对于list1,选择status等于'ready'的项目,然后只取id

        var ready_id_array = list1.filter(item=>item.status == 'ready').map(item=>item.id);
        

        对于list2,检查其uid包含在ready_id_array中的项目,并且elec大于50。

        var result = list2 .filter(item => ready_id_array.indexOf(item.uid) > -1 && item.elec > 50);
        

        要附加评论,创建一个字典,然后将评论放回结果

        var comment_dictionary = list1.reduce((a,x) => ({...a, [x.id]: x.comment}), {});
        result.forEach(item => item.comment = comment_dictionary[item.uid]);
        

        你会得到结果。

        [{uid: "2", elec: 60, comment: "yyyy"}]
        

        【讨论】:

        • 没有得到评论。
        • 对,但是我错过了 list1 的评论;)
        猜你喜欢
        • 2017-06-06
        • 1970-01-01
        • 2020-03-28
        • 2016-12-25
        • 2019-11-20
        • 2022-08-15
        • 1970-01-01
        • 2011-01-26
        • 1970-01-01
        相关资源
        最近更新 更多