如何从对象数组中过滤掉对象 关于对象 id 的基础知识



>我正在使用 react-native,我必须在另一个对象数组中提供的 id 基础知识上从对象数组中过滤掉对象。我的数组对象为:

var objArr = [
    {name:'a',id:1},
    {name:'ab',id:2},
    {name:'abc',id:3}
];
var keys = [
    {user_id:1},
    {user_id:2}
];
var filterResult = objArr.filter((f) => {
                      !this.keys.includes(f)
                   });

如何从数组中删除 id 等于键的用户 ID 的对象?

对于纯javascript,这适用于使用filter和reduce的情况,(尝试运行下面的代码片段(

var objArr = [
    {name:'a',id:1},
    {name:'ab',id:2},
    {name:'abc',id:3}
];
var keys = [
    {user_id:1},
    {user_id:2}
];
var filtered = objArr.filter( (o) => {
    return keys.reduce( (final, k) => {
        return final && !(k.user_id == o.id);
    }, true);
});
console.log(filtered);

为了防止重新发明轮子,建议为此使用现有的库。

lodash 完全可以满足您的需求,但有所不同。

所以它变得干净而优雅:

const filtered = _.differenceWith(objArr, keys, (a, b) => a.id == b.user_id);

尝试运行下面的代码片段。

var objArr = [
    {name:'a',id:1},
    {name:'ab',id:2},
    {name:'abc',id:3}
];
var keys = [
    {user_id:1},
    {user_id:2}
];
const filtered = _.differenceWith(objArr, keys, (a, b) => a.id == b.user_id);
console.log(filtered);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

使用 lodash 表示 react-native:

npm i lodash

import _ from 'lodash';

更新 2:

如果你正在做性能关键型代码,那就完全不同了。 你必须通过制作索引来调整你的代码,避免所有方便的函数,如filterreduce,改用传统的for循环。

我做了一个快速的,它比 lodash 快 50 倍(300 毫秒到 6 毫秒(,在 100k 个带有 3k 键的对象上:

var filtered = [];
var indexes = {};
for (var i=0; i<keys.length; ++i) {
    indexes[keys[i].user_id] = true;
}
for (var i=0; i<objArr.length; ++i) {
    !indexes[objArr[i].id] && filtered.push(objArr[i]);
}

/* create objects */
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}
function makeRand() {
  return Math.floor(Math.random() * 5000);
}
var objArr = [];
for (var i=0; i<100000; ++i) {
    objArr.push({
        name: guid(),
        id: makeRand()
    });
}
var keys = [];
for (var i=0; i<3000; ++i) {
    keys.push({
        user_id: makeRand()
    });
}
/* execute method 1 */
console.time('measure method 1');
var filtered = objArr.filter( (o) => {
    return keys.reduce( (final, k) => {
        return final && !(k.user_id == o.id);
    }, true);
});
console.timeEnd('measure method 1');
console.log('measure method 1 totally', filtered.length, ' objects');
/* execute method 2 */
console.time('measure method 2');
var filtered = _.differenceWith(objArr, keys, (a, b) => a.id == b.user_id);
console.timeEnd('measure method 2');
console.log('measure method 2 totally', filtered.length, ' objects');
/* execute method 3 */
console.time('measure method 3');
var filtered = [];
var indexes = {};
for (var i=0; i<keys.length; ++i) {
    indexes[keys[i].user_id] = true;
}
for (var i=0; i<objArr.length; ++i) {
    !indexes[objArr[i].id] && filtered.push(objArr[i]);
}
console.timeEnd('measure method 3');
console.log('measure method 3 totally', filtered.length, ' objects');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

执行此操作的一种

方法是将键对象减少为数字数组。这个想法是将 objArr 中的每个 element.id 与密钥数组中的 id 进行比较。这似乎是您在上面尝试执行的操作。

1(减少键:

var reducedKeys = keys.reduce((total, each) => {
   total.push(each.user_id);
   return total;
}, []);

2( 过滤掉密钥中未包含的 ID:

var filterResult = objArr.filter((each) => {
   if (!reducedKeys.includes(each.id)) {
       return each;
   }
});

如果您:

console.log(filterResult)

结果是:

[ { name: 'abc', id: 3 } ]

最新更新