【问题标题】:Filter array of objects by another array with duplicate keys通过另一个具有重复键的数组过滤对象数组
【发布时间】:2019-08-20 05:02:43
【问题描述】:

我有这个对象数组:

const data = [
    {
       id: 1,
       name: 'Name1',
       encryptionKey: 'AAA'
    },
    {
       id: 2,
       name: 'Name2',
       encryptionKey: 'BBB'
    },
    {
       id: 3,
       name: 'Name3',
       encryptionKey: 'CCC'
    }
 ]

还有另一个加密密钥数组:

const encryptionKeys = ['AAA', 'BBB']

然后我将根据encryptionKeys 数组过滤data 数组,如下所示:

var filtered = data.filter(function(item) {
   return encryptionKeys.indexOf(item.encryptionKey) !== -1;
});

工作并过滤对象并将它们保存在新数组中。但是,问题是如果encryptionKey 数组有重复的键,例如:

const encryptionKeys = ['AAA', 'BBB', 'BBB']

那么所有重复的键都将被忽略,过滤后的数组在这种情况下将只有 2 个对象而不是 3 个。我在过滤代码中做错了什么?如果encryptionKeys 数组有重复值,则过滤后的数组应该有重复的对象。

【问题讨论】:

  • 您在encryptionKeys 中是否有不在data 中的项目?
  • 你期望重复键的输出是什么
  • 所以如果BBB 存在n 次,那么您希望加密密钥为BBB 的对象出现在过滤结果n 次吗?
  • 完全是@FrancisLeigh

标签: javascript arrays reactjs object ecmascript-6


【解决方案1】:

记下.flat() 的浏览器兼容性,然后查看@babel/polyfill

const data = [
  {
    id: 1,
    name: 'Name1',
    encryptionKey: 'AAA'
  },
  {
    id: 2,
    name: 'Name2',
    encryptionKey: 'BBB'
  },
  {
    id: 3,
    name: 'Name3',
    encryptionKey: 'CCC'
  }
]
const keys = ['AAA', 'BBB', 'BBB', 'AAA', 'BBB', 'ZZZ']

const occurances = data.map(d => {
  const { encryptionKey } = d
  const keyedOccurances = keys
                        .filter(k => k === encryptionKey)
                        .map(k => encryptionKey === k && d)

  return keyedOccurances.length && keyedOccurances
})
.filter(Boolean)
.flat()

console.log(occurances)

【讨论】:

    【解决方案2】:

    简单 - 只需事先在 encryptionKeys 上使用 filter

    var filtered = data.filter(function(item) {
       return encryptionKeys.filter((e, i, a) => a.indexOf(e) == i).indexOf(item.encryptionKey) !== -1;
    });
    

    或者,从Set 创建一个Array

    var filtered = data.filter(function(item) {
       return [...new Set(encryptionKeys)].indexOf(item.encryptionKey) !== -1;
    });
    

    【讨论】:

    • 我尝试了您的解决方案,但过滤后的数组仍然只有 2 个对象而不是 3 个。
    【解决方案3】:

    在比较和过滤之前使您的加密密钥独一无二。

    var encryptionKeys = ['AAA', 'BBB', 'BBB'];
    var unique = encryptionKeys.filter((v, i, a) => a.indexOf(v) === i); 
    console.log(unique);

    【讨论】:

      【解决方案4】:

      您可以映射想要的项目。

      const
          data = [{ id: 1, name: 'Name1', encryptionKey: 'AAA' }, { id: 2, name: 'Name2', encryptionKey: 'BBB' }, { id: 3, name: 'Name3', encryptionKey: 'CCC' }],
          encryptionKeys = ['AAA', 'BBB', 'BBB'],
          result = encryptionKeys.map(key => data.find(o => o.encryptionKey === key));
           
      console.log(result);

      使用Map 并提前过滤密钥的简短方法。

      const
          data = [{ id: 1, name: 'Name1', encryptionKey: 'AAA' }, { id: 2, name: 'Name2', encryptionKey: 'BBB' }, { id: 3, name: 'Name3', encryptionKey: 'CCC' }],
          encryptionKeys = ['AAA', 'BBB', 'BBB', 'DDD'],
          map = new Map(data.map(o => [o.encryptionKey, o])),
          result = encryptionKeys
              .filter(Map.prototype.has, map)
              .map(Map.prototype.get, map);
           
      console.log(result);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-30
        • 2019-05-05
        • 2019-07-18
        • 2021-10-30
        • 1970-01-01
        • 2020-01-27
        • 2023-02-03
        • 1970-01-01
        相关资源
        最近更新 更多