lodash:创建带有最新项目的新数组



我的数组如下

[{
        "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"
    }
]

我想根据上述数组创建一个新数组,但仅使用最新项目(按项目的名称组组)。

 [{
            "id": "002",
            "name": "A",
            "timestamp_created": "2019-02-27T11:30:19"
        },
        {
            "id": "004",
            "name": "B",
            "timestamp_created": "2019-02-27T11:05:19"
        }
    ]

如何结合不同的lodash特征以实现结果?

任何建议,请帮助我。

您可以服用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; }

而无需使用库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;}

到目前为止的出色答案。正如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, {})
);

如果要使用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;
}

使用lodash

的简短解决方案
const data = [...]
const result = _(data)
  .groupBy('name')
  .map(group => _.maxBy(group, 'timestamp_created'))
  .value()

使用 groupBy通过 name 组组。然后使用maxBy获取具有最大 timestamp_created 的对象。

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

此方法就像_.max一样,除了它接受iTerateE,该元素在数组中的每个元素都被调用以生成对值排名的标准。iTerateE被一个参数调用:(value)。

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

最新更新