[英]Filter array based of two conditions
我有以下數組的對象,(例如,這里的時間點是模擬的,更大的是最后一個)
var firstArr = [{
id: 1,
a: 2,
timestemp: 111
}, {
id: 2,
a: 4,
timestemp: 222
}, {
id: 3,
a: 6,
timestemp: 333
}, {
id: 1,
a: 3,
timestemp: 777
}, {
id: 3,
a: 5555,
timestemp: 5555
}];
我需要做的是以某種方式過濾此數組並創建具有唯一值的新數組。
我最后需要
var endArr = [{
id: 1,
a: 3,
timestemp: 777
}, {
id: 2,
a: 4,
timestemp: 222
}, {
id: 3,
a: 5555,
timestemp: 555
}];
正如您所看到的,我已經通過兩件事過濾了這個數組
- uniqe ID(條目1和3只存在一次)
- timestemp(僅添加具有最后時間點的對象)
我怎么能用map / reduce / filter等數組方法做到這一點?
我試着用array.filter做這件事但沒有成功
首先,你將時間戳拼寫為時間戳。
var firstArr = [{
id: 1,
a: 2,
timestamp: 111
}, {
id: 2,
a: 4,
timestamp: 222
}, {
id: 3,
a: 6,
timestamp: 333
}, {
id: 1,
a: 3,
timestamp: 777
}, {
id: 3,
a: 5555,
timestamp: 5555
}];
這是功能:
function updateList(a_list) {
var seen = {};
for (var entry in a_list) {
var id = a_list[entry]["id"];
if (seen.hasOwnProperty(id)) {
var current_timestamp = seen[id]["timestamp"]
var check_timestamp = a_list[entry]["timestamp"]
if (current_timestamp < check_timestamp) {
seen[id] = a_list[entry];
}
} else {
seen[id] = a_list[entry];
}
}
var updated = [];
for (var newest in seen) {
updated.push(seen[newest]);
}
return updated;
}
https://jsfiddle.net/vpg3onqm/
如果這是你想要的答案,請務必按upvote和greentick。
由於需要使用filter
/ map
/ reduce
,我想我會選擇:
var lastestPerId = firstArr.reduce(function(state, curr) {
if(state[curr.id]){ // We've seen this id before
if(curr.timestemp > state[curr.id].timestemp) { // and its later
state[curr.id] = curr; // so, update this item to be the latest item
}
} else {
state[curr.id] = curr; // add because unknown
}
return state; // pass along the state to the next item in the array
}, {});
var endArr = Object.keys(lastestPerId)
.map(function (key) {return bestPerId[key]});
這將創建一個初始狀態( {}
),循環遍歷firstArr
每個項目。 它試圖找出id
是否已知,如果是,它保持跟蹤( state
)具有最高時間點的timestemp
。 對於firstArr
每個元素傳遞state
。 因為結果是一個對象( id
s鍵,實際項為value),我們需要將其map
回數組。
如果firstArr
按時間戳排序,則此方法有效。 返回的數組也將按時間戳排序。
從數組的末尾開始(更大的時間戳),如果尚未找到新數組中的當前元素,請將其包括在內。 found
數組用於跟蹤提取的元素。
var found = [];
firstArr.reverse().filter( function(el){
if( found.indexOf( el.id ) === -1 ){
found.push( el.id );
return true;
}
return false;
}).reverse();
groupBy是你的朋友: https ://lodash.com/docs#groupBy
_(firstArr)
.groupBy('id')
.map(function(x) {
return _(x).orderBy(x,['timestemp'], ['desc']).head();
})
.value();
您可以使用orderBy()和uniqBy()來獲取具有最新時間戳的唯一ID的所有項:
var firstArr = [{ id: 1, a: 2, timestamp: 111 }, { id: 2, a: 4, timestamp: 222 }, { id: 3, a: 6, timestamp: 333 }, { id: 1, a: 3, timestamp: 777 }, { id: 3, a: 5555, timestamp: 5555 }]; var result = _(firstArr) .orderBy(['id', 'timestamp'], ['asc', 'desc']) .uniqBy('id') .value(); console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
您可以排序然后過濾第一個id出現:
var firstArr = [ { id: 1, a: 2, timestemp: 111 }, { id: 2, a: 4, timestemp: 222 }, { id: 3, a: 6, timestemp: 333 }, { id: 1, a: 3, timestemp: 777 }, { id: 3, a: 5555, timestemp: 5555 } ]; // sort firstArr by decrescent timestamp: firstArr.sort((x,y)=>y.timestemp-x.timestemp); // get only the first occurrence of each id: var endArr = firstArr.filter((o,i)=>i==firstArr.findIndex(u=>u.id==o.id)); // job finished output.innerHTML = JSON.stringify( endArr, null, 2 );
<pre id=output>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.