簡體   English   中英

根據兩個條件過濾數組

[英]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
}];

正如您所看到的,我已經通過兩件事過濾了這個數組

  1. uniqe ID(條目1和3只存在一次)
  2. 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();

https://jsfiddle.net/koljada/53esaqLz/3/

您可以使用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.

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