Lodash:使用最新项目创建新数组

时间:2019-02-27 15:19:28

标签: javascript arrays lodash

我有一个如下数组

MissingValue

我想基于上述数组创建一个新数组,但仅包含最新项(按项名称分组)。

INotifyPropertyChanged

如何结合Lodash的不同功能以获得结果?

任何建议,请帮助我。

5 个答案:

答案 0 :(得分:3)

您可以使用Map,收集所有最新项(通过检查timestamp_created),按name分组并获取值。

var data = [{ id: "002", name: "A", timestamp_created: "2019-02-27T11:30:19" }, { id: "003", name: "B", timestamp_created: "2019-02-27T10:15:19" }, { id: "004", name: "B", timestamp_created: "2019-02-27T11:05:19" }, { id: "001", name: "A", timestamp_created: "2019-02-27T11:22:19" }],
    result = Array.from(data
        .reduce(
            (m, o) => m.has(o.name) && m.get(o.name).timestamp_created > o.timestamp_created
               ? m
               : m.set(o.name, o),
            new Map
        )
        .values()
    );
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:2)

无需使用库lodash,就可以使用 Array.reduce() 生成结果:

const input = [
    {
        "id": "001",
        "name": "A",
        "timestamp_created": "2019-02-27T11:22:19"
    },
    {
        "id": "002",
        "name": "A",
        "timestamp_created": "2019-02-27T11:30:19"
    },
    {
        "id": "003",
        "name": "B",
        "timestamp_created": "2019-02-27T10:15:19"
    },
    {
        "id": "004",
        "name": "B",
        "timestamp_created": "2019-02-27T11:05:19"
    }
];

let res = input.reduce((acc, {id, name, timestamp_created}) =>
{
    acc[name] = acc[name] || {id, name, timestamp_created};
    
    if (acc[name].timestamp_created < timestamp_created)
        acc[name] = {id, name, timestamp_created};    

    return acc;
}, {});

console.log(Object.values(res));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

答案 2 :(得分:2)

如果您想使用lodash,就可以完成这项工作。

function latestItems(original) {
    filtered = [];
    grouped = _.groupBy(original, "name");
    _.forEach(grouped, function (group) {
        newest = {
            "timestamp_created": "0"
        };
        _.forEach(group, function (item) {
            if (item.timestamp_created > newest.timestamp_created) {
                newest = item;
            }
        });
        filtered.push(newest);
    });

    return filtered;
}

答案 3 :(得分:2)

到目前为止,很好的答案。当OP要求Lodash解决方案时,就是这样:

const data = [{
    "id": "001",
    "name": "A",
    "timestamp_created": "2019-02-27T11:22:19"
},
{
    "id": "002",
    "name": "A",
    "timestamp_created": "2019-02-27T11:30:19"
},
{
    "id": "003",
    "name": "B",
    "timestamp_created": "2019-02-27T10:15:19"
},
{
    "id": "004",
    "name": "B",
    "timestamp_created": "2019-02-27T11:05:19"
}
];

const reduceFunction = (acc, val) => {
    if (val.name in acc) {
        if (val.timestamp_created > acc[val.name].timestamp_created) {
            acc[val.name] = val
        }
    } else {
        acc[val.name] = val
    }

    return acc;
};

const filteredData = _.values(
    _.reduce(data, reduceFunction, {})
);

答案 4 :(得分:2)

使用lodash的简短解决方案

const data = [...]
const result = _(data)
  .groupBy('name')
  .map(group => _.maxBy(group, 'timestamp_created'))
  .value()

使用groupBy名称分组。然后使用maxBy获取具有最大 timestamp_created 的对象。

  

_.maxBy(array, [iteratee=_.identity])

     
    

此方法类似于_.max,不同之处在于它接受iteratee,后者会为数组中的每个元素调用以生成用于对值进行排名的条件。使用一个参数(值)调用iteratee。

  
     

https://lodash.com/docs/4.17.11#maxBy