我正在使用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?
答案 0 :(得分:0)
您可以这样做的一种方法是将密钥对象减少为一组数字。我们的想法是将objArr中的每个element.id与keys数组中的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 } ]
答案 1 :(得分:0)
对于纯JavaScript,这适用于您的情况与过滤器&减少,(尝试在代码片段下面运行)
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使用differenceWith完全符合您的要求。
所以它变得干净优雅:
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>
npm i lodash
和
import _ from 'lodash';
如果您正在执行性能关键代码,那就完全不同了。您必须通过制作索引来调整代码,避免使用filter
,reduce
等所有便捷功能,而是使用传统的for循环。
我做了一个快速的,它比lodash(300毫秒到6毫秒)快了大约50倍,在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>