我有以下数组的对象,(比如说这里的时间点是模拟的,而后者是最后一个)
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而没有成功
答案 0 :(得分:0)
首先,您将时间戳拼写为时间戳。
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。
答案 1 :(得分:0)
由于要求使用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
的项目。 state
为firstArr
中的每个元素传递id
。因为结果是一个对象(以map
为键,实际项为值),我们需要{{1}}将其返回数组。
答案 2 :(得分:0)
如果firstArr
按时间戳排序,则此方法有效。返回的数组也将按时间戳排序。
从数组的末尾开始(更大的时间戳),如果尚未找到新数组,请包含当前元素。 found
数组用于跟踪提取的元素。
var found = [];
firstArr.reverse().filter( function(el){
if( found.indexOf( el.id ) === -1 ){
found.push( el.id );
return true;
}
return false;
}).reverse();
答案 3 :(得分:0)
groupBy是你的朋友:https://lodash.com/docs#groupBy
_(firstArr)
.groupBy('id')
.map(function(x) {
return _(x).orderBy(x,['timestemp'], ['desc']).head();
})
.value();
答案 4 :(得分:0)
您可以使用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>
答案 5 :(得分:0)
您可以排序,然后过滤首次出现的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>