简体   繁体   English

如何在对象ID的基础上从对象数组中过滤出对象

[英]How to filter out objects from array of object on the basics of object id

I am using react-native where i have to filter out the objects from object array on the basics of id which is provides in another array of object. 我正在使用react-native,其中我必须根据另一个对象数组中提供的id的基础从对象数组中过滤出对象。 i have array object as: 我有数组对象为:

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)
                   });

how to remove objects from array where id is equal to user id of keys? 如何从ID等于键的用户ID的数组中删除对象?

One way you could do this is to reduce your keys objects to an array of numbers. 您可以执行此操作的一种方法是将键对象减少为数字数组。 The idea is to compare each element.id in your objArr to the ids in your keys array. 这个想法是将objArr中的每个element.id与key数组中的id进行比较。 This seems like what you're trying to do above. 这似乎是您要在上方执行的操作。

1) Reduce keys: 1)减少键:

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

2) Filter out ids not included in keys: 2)过滤掉键中不包含的ID:

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

If you: 如果你:

console.log(filterResult)

the result is: 结果是:

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

For pure javascript, this works for your case with filter & reduce, (try run below code snippet) 对于纯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); 

To prevent reinventing the wheel, suggest to use existing library for this. 为了避免重新发明轮子,建议为此使用现有的库。

lodash does exactly what you need, with differenceWith . lodash不正是你所需要的,具有differenceWith

So it becomes clean and elegant: 因此它变得干净优雅:

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

Try run code snippet below. 请尝试下面的运行代码段。

 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> 

Use lodash for react-native: 将lodash用于本机反应:

npm i lodash

and

import _ from 'lodash';

Update 2: 更新2:

If you're doing performance critical code, that's a totally different story. 如果您正在执行性能关键的代码,那就完全不一样了。 you have to tune your code by making index, avoid all handy functions like filter , reduce , use traditional for-loop instead. 您必须通过建立索引来调整代码,避免使用所有方便的函数,例如filterreduce ,而是使用传统的for循环。

I made a quick one, it's about 50 times faster than lodash (300 ms to 6 ms), on 100k of objects with 3k of keys: 我做了一个快速的例子,它在100k个带有3k键的对象上比lodash(300毫秒至6毫秒)快50倍:

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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM