簡體   English   中英

JavaScript 按來自另一個的數據過濾數組

[英]JavaScript filter array by data from another

我有一個數組對象:

[
    { id:1, name: 'Pedro'},
    { id:2, name: 'Miko'},
    { id:3, name: 'Bear'},
    { id:4, name: 'Teddy'},
    { id:5, name: 'Mouse'}
]

我有一個 ID 為 [1, 3, 5] 的數組,

如何過濾數組對象以僅保留第二個 id 的記錄?

如果支持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);

如果不支持包含,您可以使用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);

也許將Array.prototype.reduceArray.prototype.some結合使用。 這將保持給定數組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>');

為了保持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>');

如果數據集很小,您可以使用任何提供的解決方案(使用 indexOf 的解決方案)。

然而,這些解決方案是 O(n^2) 的,因此,如果數據集足夠大,滯后會變得明顯。 在這種情況下,您應該在選擇元素之前構建索引。

例子:

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

一些基准測試可以在這里進行測試。

您可以在對象數組上使用 for 循環,並在另一個 for 循環中為[1,3,5]每個 id 檢查hasOwnProperty (一旦找到 id 就跳出循環)。 (一旦找到所有 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;
}

或使用array.splice( i, 1 ); 如果你不想要一個空插槽。

使用filterindexOf可以解決問題:

var filteredArray = dataArray.filter(function(obj) {
  return idsArray.indexOf(obj.id) > -1;
});

但是, indexOf具有線性性能,並且會被多次調用。

在 ES6 中,您可以使用 set 代替,其has調用具有次線性性能(平均):

var idsSet = new Set(idsArray),
    filteredArray = dataArray.filter(obj => idsSet.has(obj.id));

假設你的 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];
});

您可以在 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
    });
}

在這個 JSFiddle 中查看它的實際效果

或者,如果您使用的是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM