如何从数组中选择每个用户的最新项目?

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降序排列。由于 createdAtDate,因此需要这样处理。方便的是,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; }