我试图找到一种更好的方法来迭代Javascript中的一个对象数组,我还想做两个更多的功能
例如,
var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
var matchedArray = originalArray.filter(function(n, i, arr) {
return (n.id == 1 || n.id == 2 || n.id == 5) && arr.splice(i, 1)
});
输出我正在寻找
原始数组为:[{id:3},{id:4}]
匹配数组为:[{id:1},{id:2},{id:5}]
答案 0 :(得分:2)
这是一个泛型函数partition
:给定一个数组和一个谓词(= boolean)函数,它将数组拆分为“falsy”和“truthy”部分:
function partition (ary, predicate) {
var rs = [[], []];
ary.forEach(function(x) {
rs[predicate(x) ? 1 : 0].push(x);
});
return rs;
};
///
var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
var parts = partition(originalArray, function(n) {
return n.id == 1 || n.id == 2 || n.id == 5
});
console.log(JSON.stringify(parts[0]));
console.log(JSON.stringify(parts[1]))
答案 1 :(得分:2)
如果删除了一个元素,那么在下一次迭代中,实际的元素索引和回调中的索引会有所不同,这会导致意外输出。
使用while循环以相反的顺序迭代并生成新数组并从主数组中删除该值。虽然您可以使用数组并使用Array#includes
方法检查数组中存在的值来避免多种情况(对于较旧的浏览器支持,请使用Array#indexOf
方法)。
var matchedArray = [],
i = originalArray.length;
while (i--) {
if ([1, 2, 5].includes(originalArray[i].id))
matchedArray.push(originalArray.splice(i, 1)[0])
}
var originalArray = [{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}, {
id: 5
}];
var matchedArray = [],
i = originalArray.length;
while (i--) {
if ([1, 2, 5].includes(originalArray[i].id))
matchedArray.push(originalArray.splice(i, 1)[0])
}
console.log(matchedArray);
console.log(originalArray);
更新1:使用Array#reduceRight
方法使用相同逻辑的替代方法。
var matchedArray = originalArray.reduceRight(function(arr, o, i, orig) {
if ([1, 2, 5].includes(o.id))
arr.push(orig.splice(i, 1)[0])
return arr;
}, [])
var originalArray = [{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}, {
id: 5
}];
var matchedArray = originalArray.reduceRight(function(arr, o, i, orig) {
if ([1, 2, 5].includes(o.id))
arr.push(orig.splice(i, 1)[0])
return arr;
}, [])
console.log(matchedArray);
console.log(originalArray);
更新2:虽然您可以使用Array#filter
方法执行此操作,但附加变量会保留已删除元素的数量,这有助于计算更新数组上的新索引。
var c = 0;
var matchedArray = originalArray.filter(function(n, i, arr) {
return [1, 2, 5].includes(n.id) && arr.splice(i - c--, 1)
});
var originalArray = [{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}, {
id: 5
}];
var c = 0;
var matchedArray = originalArray.filter(function(n, i, arr) {
return [1, 2, 5].includes(n.id) && arr.splice(i - c--, 1)
});
console.log(matchedArray);
console.log(originalArray);
答案 2 :(得分:0)
可能的解决方案之一。您可以调整ids
数组并指定要过滤的ID。
var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
var ids = [1,2,5];
var filtered = [];
var notFiltered = [];
filtered = originalArray.filter(v => ids.some(c => c == v.id));
notFiltered = originalArray.filter(v => filtered.every(c => c.id != v.id));
console.log(filtered);
console.log(notFiltered);

答案 3 :(得分:0)
你可以使用Lodash中的_.remove函数来解决这个问题。
let originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
const matchedArray = _.remove(originalArray, function(n) {
return (n.id == 1 || n.id == 2 || n.id == 5);
});
console.log(originalArray);
console.log(matchedArray);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
答案 4 :(得分:0)
使用underscoreJs例如:
var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
var matchedArray = _.filter(originalArray,function(n){return (n.id == 1 || n.id == 2 || n.id == 5);});
originalArray = _.difference(originalArray,matchedArray);