如何从数组中选择每个用户的最新项目?
How to pick latest item per user from an array?
例如,我有一个这样的数组:
[
{
"data": "some data",
"user": "A",
"createdAt":"2016-12-24",
},
{
"data": "some data2",
"user": "B",
"createdAt":"2016-12-24",
},
{
"data": "some data3",
"user": "A",
"createdAt":"2016-12-25",
},
{
"data": "some data4",
"user": "A",
"createdAt":"2016-12-23",
},
{
"data": "some data5",
"user": "B",
"createdAt":"2016-12-25",
},
{
"data": "some data6",
"user": "C",
"createdAt":"2016-12-24",
},
]
我只需要每个用户最新创建的项目,所以我需要这样的数组:
[
{
"data": "some data3",
"user": "A",
"createdAt":"2016-12-25",
},
{
"data": "some data5",
"user": "B",
"createdAt":"2016-12-25",
},
{
"data": "some data6",
"user": "C",
"createdAt":"2016-12-24",
},
]
如何使用下划线或 lodash 来实现?
lodash 提供 orderBy
and uniqBy
方法。
关键是先按user
再按createdAt
降序排列。由于 createdAt
是 Date
,因此需要这样处理。方便的是,orderBy
方法允许指定要排序的 属性 或要评估的函数(returns 要排序的对象,在本例中为 Date
) .
var data = [{
"data": "some data",
"user": "A",
"createdAt": "2016-12-24",
}, {
"data": "some data2",
"user": "B",
"createdAt": "2016-12-24",
}, {
"data": "some data3",
"user": "A",
"createdAt": "2016-12-25",
}, {
"data": "some data4",
"user": "A",
"createdAt": "2016-12-23",
}, {
"data": "some data5",
"user": "B",
"createdAt": "2016-12-25",
}, {
"data": "some data6",
"user": "C",
"createdAt": "2016-12-24",
}],
sorted = _.orderBy(
data,
['user', function(d) {
return new Date(d.createdAt)
}],
['asc', 'desc'] // 'desc' orders by date descending
),
uniqued = _.uniqBy(sorted, 'user');
console.log(uniqued);
对于普通的javascript,你可以这样做
var myArray = [
{
"data": "some data",
"user": "A",
"createdAt":"2016-12-24",
},
{
"data": "some data2",
"user": "B",
"createdAt":"2016-12-24",
},
{
"data": "some data3",
"user": "A",
"createdAt":"2016-12-25",
},
{
"data": "some data4",
"user": "A",
"createdAt":"2016-12-23",
},
{
"data": "some data5",
"user": "B",
"createdAt":"2016-12-25",
},
{
"data": "some data6",
"user": "C",
"createdAt":"2016-12-24",
},
]
function getLatestItems(itemArray) {
var latestItemPerUser = {}, latesItems = [], newDate, oldDate;
for(var i = 0, l = itemArray.length; i < l; ++i) {
if(!latestItemPerUser[itemArray[i].user]) {
latestItemPerUser[itemArray[i].user] = itemArray[i];
} else {
newDate = new Date(itemArray[i].createdAt);
oldDate = new Date(latestItemPerUser[itemArray[i].user].createdAt);
if(oldDate < newDate) {
latestItemPerUser[itemArray[i].user] = itemArray[i];
}
}
}
for(var item in latestItemPerUser) {
latesItems.push(latestItemPerUser[item]);
}
return latesItems;
}
console.log(getLatestItems(myArray));
另一个简单的解决方案 Javascript,带有散列 table 和稍后的检查 createdAt
。
var data = [{ "data": "some data", "user": "A", "createdAt": "2016-12-24", }, { "data": "some data2", "user": "B", "createdAt": "2016-12-24", }, { "data": "some data3", "user": "A", "createdAt": "2016-12-25", }, { "data": "some data4", "user": "A", "createdAt": "2016-12-23", }, { "data": "some data5", "user": "B", "createdAt": "2016-12-25", }, { "data": "some data6", "user": "C", "createdAt": "2016-12-24", }],
result = data.reduce(function (hash) {
return function (r, a) {
if (!(a.user in hash)) {
hash[a.user] = r.push(a) - 1;
return r;
}
if (r[hash[a.user]].createdAt < a.createdAt) {
r[hash[a.user]] = a;
}
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
例如,我有一个这样的数组:
[
{
"data": "some data",
"user": "A",
"createdAt":"2016-12-24",
},
{
"data": "some data2",
"user": "B",
"createdAt":"2016-12-24",
},
{
"data": "some data3",
"user": "A",
"createdAt":"2016-12-25",
},
{
"data": "some data4",
"user": "A",
"createdAt":"2016-12-23",
},
{
"data": "some data5",
"user": "B",
"createdAt":"2016-12-25",
},
{
"data": "some data6",
"user": "C",
"createdAt":"2016-12-24",
},
]
我只需要每个用户最新创建的项目,所以我需要这样的数组:
[
{
"data": "some data3",
"user": "A",
"createdAt":"2016-12-25",
},
{
"data": "some data5",
"user": "B",
"createdAt":"2016-12-25",
},
{
"data": "some data6",
"user": "C",
"createdAt":"2016-12-24",
},
]
如何使用下划线或 lodash 来实现?
lodash 提供 orderBy
and uniqBy
方法。
关键是先按user
再按createdAt
降序排列。由于 createdAt
是 Date
,因此需要这样处理。方便的是,orderBy
方法允许指定要排序的 属性 或要评估的函数(returns 要排序的对象,在本例中为 Date
) .
var data = [{
"data": "some data",
"user": "A",
"createdAt": "2016-12-24",
}, {
"data": "some data2",
"user": "B",
"createdAt": "2016-12-24",
}, {
"data": "some data3",
"user": "A",
"createdAt": "2016-12-25",
}, {
"data": "some data4",
"user": "A",
"createdAt": "2016-12-23",
}, {
"data": "some data5",
"user": "B",
"createdAt": "2016-12-25",
}, {
"data": "some data6",
"user": "C",
"createdAt": "2016-12-24",
}],
sorted = _.orderBy(
data,
['user', function(d) {
return new Date(d.createdAt)
}],
['asc', 'desc'] // 'desc' orders by date descending
),
uniqued = _.uniqBy(sorted, 'user');
console.log(uniqued);
对于普通的javascript,你可以这样做
var myArray = [
{
"data": "some data",
"user": "A",
"createdAt":"2016-12-24",
},
{
"data": "some data2",
"user": "B",
"createdAt":"2016-12-24",
},
{
"data": "some data3",
"user": "A",
"createdAt":"2016-12-25",
},
{
"data": "some data4",
"user": "A",
"createdAt":"2016-12-23",
},
{
"data": "some data5",
"user": "B",
"createdAt":"2016-12-25",
},
{
"data": "some data6",
"user": "C",
"createdAt":"2016-12-24",
},
]
function getLatestItems(itemArray) {
var latestItemPerUser = {}, latesItems = [], newDate, oldDate;
for(var i = 0, l = itemArray.length; i < l; ++i) {
if(!latestItemPerUser[itemArray[i].user]) {
latestItemPerUser[itemArray[i].user] = itemArray[i];
} else {
newDate = new Date(itemArray[i].createdAt);
oldDate = new Date(latestItemPerUser[itemArray[i].user].createdAt);
if(oldDate < newDate) {
latestItemPerUser[itemArray[i].user] = itemArray[i];
}
}
}
for(var item in latestItemPerUser) {
latesItems.push(latestItemPerUser[item]);
}
return latesItems;
}
console.log(getLatestItems(myArray));
另一个简单的解决方案 Javascript,带有散列 table 和稍后的检查 createdAt
。
var data = [{ "data": "some data", "user": "A", "createdAt": "2016-12-24", }, { "data": "some data2", "user": "B", "createdAt": "2016-12-24", }, { "data": "some data3", "user": "A", "createdAt": "2016-12-25", }, { "data": "some data4", "user": "A", "createdAt": "2016-12-23", }, { "data": "some data5", "user": "B", "createdAt": "2016-12-25", }, { "data": "some data6", "user": "C", "createdAt": "2016-12-24", }],
result = data.reduce(function (hash) {
return function (r, a) {
if (!(a.user in hash)) {
hash[a.user] = r.push(a) - 1;
return r;
}
if (r[hash[a.user]].createdAt < a.createdAt) {
r[hash[a.user]] = a;
}
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }