【问题标题】:How to filter an object using values of an array in Javascript?如何使用Javascript中的数组值过滤对象?
【发布时间】:2020-04-22 18:57:49
【问题描述】:

我有一个这样的对象(这就是我们在 chrome 开发工具中看到对象的方式):

obj: {
  1: {...},
  2: {...},
  3: {...},
  4: {...},
  5: {...},
}

我有一个像这样的简单数组:

arr: [1,3,5,7]

基本上我希望我的对象只保留数组中的键,如下所示:

obj: {
  1: {...},
  3: {...},
  5: {...},
}

目前我的代码是这样的:

var select = (arr, obj) => arr.reduce((r, e) => 
  Object.assign(r, obj[e] ? { [e]: obj[e] } : null)
, {});

var output = select(arr, obj);

我不知道为什么,但这有时有效,有时无效。我不能使用 Jquery。 谁能帮帮我?

【问题讨论】:

  • enter code here 是什么?什么时候不起作用?你有示例数据吗?代码看起来不错
  • 你的代码没问题。当它不起作用时你遇到了什么错误?
  • obj[e] ? 不是正确的检查(因为虚假值可能不是您想要检查的)。 e in obj ? 会更准确。

标签: javascript arrays vue.js ecmascript-6


【解决方案1】:

您可以使用Object.fromEntries()Object.entries()Array.prototype.filter()Array.prototype.includes() 过滤掉不在arr 内的键:

const obj ={
  1: {},
  2: {},
  3: {},
  4: {},
  5: {},
};

const arr = [1, 3, 5, 7];

const filtered = Object.fromEntries(
  // Note `key` is an `string` here, thus the `+`:
  Object.entries(obj).filter(([key]) => arr.includes(+key))
);

console.log(filtered);

或者一个简单的for 循环,在这种情况下是for...of,再次使用Array.prototype.includes() 来选择你想要的(而不是过滤你不想要的)和Object.prototype.hasOwnProperty() 以避免添加不' t 存在于obj:

const obj ={
  1: {},
  2: {},
  3: {},
  4: {},
  5: {},
};

const arr = [1, 3, 5, 7];

const filtered = {};

for (const key of arr) { 
  // Note the `hasOwnProperty` check here to avoid adding the key `7` with a value of `undefined`:
  if (obj.hasOwnProperty(key)) filtered[key] = obj[key];
}

console.log(filtered);

或者你也可以使用Array.prototype.reduce()

const obj ={
  1: {},
  2: {},
  3: {},
  4: {},
  5: {},
};

const arr = [1, 3, 5, 7];

const filtered = arr.reduce((newObj, key) => {
  // Note we add the values to `newObj` rather than `filtered` now:
  if (obj.hasOwnProperty(key)) newObj[key] = obj[key];
  
  // And you always need to return `newObj`:
  return newObj;
}, { })

console.log(filtered);

最后,如果你已经在使用Lodash,你可以使用_.pick

const obj ={
  1: {},
  2: {},
  3: {},
  4: {},
  5: {},
};

const arr = [1, 3, 5, 7];

const filtered = _.pick(obj, arr);

console.log(filtered);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script>

【讨论】:

    【解决方案2】:

    在现代环境中(或使用适当的 polyfill),您可以使用 Object.entriesArray.prototype.filterObject.fromEntries,如下所示:

    const result = Object.fromEntries(
        Object.entries(obj)
            .filter(([key, value]) => arr.includes(+key))
    );
    

    现场示例:

    const obj = {
      1: {name: "one"},
      2: {name: "two"},
      3: {name: "three"},
      4: {name: "four"},
      5: {name: "five"},
    };
    
    const arr = [1,3,5,7];
    
    const result = Object.fromEntries(
        Object.entries(obj)
            .filter(([key, value]) => arr.includes(+key))
    );
    
    console.log(result);

    ...但您也可以采用简单的循环方法:

    const result = {};
    for (const [key, value] of Object.entries(obj)) {
        if (arr.includes(+key)) {
            result[key] = value;
        }
    }
    

    现场示例:

    const obj = {
      1: {name: "one"},
      2: {name: "two"},
      3: {name: "three"},
      4: {name: "four"},
      5: {name: "five"},
    };
    
    const arr = [1,3,5,7];
    
    const result = {};
    for (const [key, value] of Object.entries(obj)) {
        if (arr.includes(+key)) {
            result[key] = value;
        }
    }
    
    console.log(result);

    在上述两种情况下,请注意filter 调用中key 之前的+。该数组包含数字,但对象的属性键始终是字符串或符号(在您的情况下为字符串)。所以我们必须转换为includes 才能找到它们。

    【讨论】:

      猜你喜欢
      • 2021-01-30
      • 2022-10-14
      • 1970-01-01
      • 2021-04-23
      • 2020-07-21
      • 2018-11-22
      • 2020-07-03
      • 1970-01-01
      相关资源
      最近更新 更多