如何从集合中按数组值获取元素?原生JS及Lodash实现方案
好问题!我来帮你梳理下两种最贴合需求的简洁实现方式——原生JS和Lodash的方案,既能保证效率,又能完美匹配你要的输出顺序:
原生JS最优最简实现
如果要兼顾执行效率和输出顺序匹配ids数组,最优的方式是先把集合转成以id为键的映射,再遍历ids数组提取对应元素。这种方法的时间复杂度是O(n),比filter+indexOf的O(n*m)高效得多,代码也非常简洁:
const ids = [1, 2, 3, 4]; const collection = [{id: 2}, {id: 234}, {id:1}, {id: 345}, {id: 3}, {id:4}, {id:323}]; // 第一步:构建id到元素的映射 const idToItem = new Map(collection.map(item => [item.id, item])); // 第二步:按ids顺序提取元素 const result = ids.map(id => idToItem.get(id)); console.log(result); // 输出:[{id: 1}, {id: 2}, {id: 3}, {id: 4}]
如果你只是想快速写短代码,且不担心少量数据的效率问题,也可以用filter配合Set(比indexOf查找更快),但注意这种方式得到的元素顺序是它们在collection中出现的顺序,需要额外排序才能匹配预期输出:
const idSet = new Set(ids); const result = collection.filter(item => idSet.has(item.id)) .sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
不过显然第一种映射+遍历的方式更优。
Lodash内置方法实现
Lodash提供了非常简洁的组合方法来完成这个需求,用_.keyBy+_.at就能一步到位,完美匹配输出顺序:
const ids = [1, 2, 3, 4]; const collection = [{id: 2}, {id: 234}, {id:1}, {id: 345}, {id: 3}, {id:4}, {id:323}]; const result = _.at(_.keyBy(collection, 'id'), ids); console.log(result); // 输出:[{id: 1}, {id: 2}, {id: 3}, {id: 4}]
_.keyBy会把集合转成以指定属性(这里是id)为键的对象,_.at则根据传入的键数组(ids)按顺序提取对应值,完全符合你的预期。
另外也可以用_.map配合_.keyBy,写法也很直观:
const result = _.map(ids, id => _.keyBy(collection, 'id')[id]);
内容的提问来源于stack exchange,提问作者wudoem
相关产品推荐
相关产品推荐

