[英]JavaScript filter array by data from another
I have an array object:我有一个数组对象:
[
{ id:1, name: 'Pedro'},
{ id:2, name: 'Miko'},
{ id:3, name: 'Bear'},
{ id:4, name: 'Teddy'},
{ id:5, name: 'Mouse'}
]
And I have an array with ids [1, 3, 5],我有一个 ID 为 [1, 3, 5] 的数组,
How can I filter the array object to leave records only with id's from the second one?如何过滤数组对象以仅保留第二个 id 的记录?
If Array.includes()
is supported, you can use it with Array.filter()
to get the items:如果支持
Array.includes()
则可以将其与Array.filter()
一起使用以获取项目:
const array = [ { id: 1, name: 'Pedro'}, { id: 2, name: 'Miko'}, { id: 3, name: 'Bear'}, { id: 4, name: 'Teddy'}, { id: 5, name: 'Mouse'} ]; const filterArray = [1,3,5]; const result = array.filter(({ id }) => filterArray.includes(id)); console.log(result);
If includes is not supported, you can use Array.indexOf()
instead:如果不支持包含,您可以使用
Array.indexOf()
代替:
var array = [ { id: 1, name: 'Pedro'}, { id: 2, name: 'Miko'}, { id: 3, name: 'Bear'}, { id: 4, name: 'Teddy'}, { id: 5, name: 'Mouse'} ]; var filterArray = [1,3,5]; var result = array.filter(function(item) { return filterArray.indexOf(item.id) !== -1; }); console.log(result);
Maybe take a Array.prototype.reduce
in combination with an Array.prototype.some
.也许将
Array.prototype.reduce
与Array.prototype.some
结合使用。 This keeps the order of the given array need
.这将保持给定数组
need
的顺序。
var data = [ { id: 3, name: 'Bear' }, { id: 4, name: 'Teddy' }, { id: 5, name: 'Mouse' }, { id: 1, name: 'Pedro' }, { id: 2, name: 'Miko' }, ], need = [1, 3, 5], filtered = need.reduce(function (r, a) { data.some(function (el) { return a === el.id && r.push(el); }); return r; }, []); document.write('<pre>' + JSON.stringify(filtered, 0, 4) + '</pre>');
To keep the order of data
you can use Array.prototype.filter
:为了保持
data
的顺序,您可以使用Array.prototype.filter
:
var data = [ { id: 3, name: 'Bear' }, { id: 4, name: 'Teddy' }, { id: 5, name: 'Mouse' }, { id: 1, name: 'Pedro' }, { id: 2, name: 'Miko' }, ], need = [1, 3, 5], filtered = data.filter(function (a) { return ~need.indexOf(a.id); }); document.write('<pre>' + JSON.stringify(filtered, 0, 4) + '</pre>');
In case the data set is small, you are ok with any of the offered solution (ones that use indexOf).如果数据集很小,您可以使用任何提供的解决方案(使用 indexOf 的解决方案)。
However, these solutions are O(n^2) ones, therefore, given the data set big enough, the lag can become noticeable.然而,这些解决方案是 O(n^2) 的,因此,如果数据集足够大,滞后会变得明显。 In this case, you should build an index prior to selecting elements.
在这种情况下,您应该在选择元素之前构建索引。
Example:例子:
function filterFast(data, ids) {
var index = ids.reduce(function(a,b) {a[b] = 1; return a;}, {});
return data.filter(function(item) {
return index[item.id] === 1;
});
}
You can use a for loop on the object array and check hasOwnProperty
in another for loop for each ids in [1,3,5]
(break out of the loop once an id found).您可以在对象数组上使用 for 循环,并在另一个 for 循环中为
[1,3,5]
每个 id 检查hasOwnProperty
(一旦找到 id 就跳出循环)。 (And break out of the bigger for-loop once all ids are found) If your array object is ordered (eg elements sorted from smallest id to biggest id) and so are your list, this solution should be quite efficient. (一旦找到所有 id,就跳出更大的 for 循环)如果您的数组对象是有序的(例如,元素从最小 id 到最大 id 排序),那么您的列表也是如此,这个解决方案应该非常有效。
var c = 0;
for(var i =0; i< objects.length; i++){
for(var v =0; v< list.length; v++)
if(objects[i].hasOwnProperty(list[v])){
delete objects[i]; c++; break;
}
if(c===list.length) break;
}
or use array.splice( i, 1 );
或使用
array.splice( i, 1 );
if you don't want an empty slot.如果你不想要一个空插槽。
Using filter
and indexOf
will do the trick:使用
filter
和indexOf
可以解决问题:
var filteredArray = dataArray.filter(function(obj) {
return idsArray.indexOf(obj.id) > -1;
});
However, indexOf
has linear performance, and it will be called lots of times.但是,
indexOf
具有线性性能,并且会被多次调用。
In ES6 you can use a set instead, whose has
call has sublinear performance (on average):在 ES6 中,您可以使用 set 代替,其
has
调用具有次线性性能(平均):
var idsSet = new Set(idsArray),
filteredArray = dataArray.filter(obj => idsSet.has(obj.id));
Assuming the toString
method of your ids is injective, you can achieve something similar in ES5:假设你的 ids 的
toString
方法是单射的,你可以在 ES5 中实现类似的东西:
var idsHash = Object.create(null);
idsArray.forEach(function(id) {
idsHash[id] = true;
});
var filteredArray = dataArray.filter(function(obj) {
return idsHash[obj.id];
});
You can use the filter method on your Array:您可以在 Array 上使用filter 方法:
var data = [
{ id:1, name: 'Pedro'},
{ id:2, name: 'Miko'},
{ id:3, name: 'Bear'},
{ id:4, name: 'Teddy'},
{ id:5, name: 'Mouse'}
];
var ids = [1, 3, 5];
var filteredData = filterData(data, 'id', ids[1]);
function filterData(data, prop, values) {
return data.filter(function(item) {
return ~values.indexOf(item[prop]); // ~ returns 0 if indexOf returns -1
});
}
See it in action in this JSFiddle .在这个 JSFiddle 中查看它的实际效果。
Or if you are using jQuery, another option may be:或者,如果您使用的是 jQuery,另一种选择可能是:
var arr1 = [1, 3, 5],
arr2 = [{ id: 1, name: 'Pedro' },
{ id: 2, name: 'Miko' },
{ id: 3, name: 'Bear' },
{ id: 4, name: 'Teddy' },
{ id: 5, name: 'Mouse' }],
filtered = $.grep(arr2, function (item) {
if (arr1.indexOf(item.id) > -1) {
return true;
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.