有没有一个简单的方法来合并ES6映射在一起(像Object.assign)?说到这里,ES6集合(比如Array.concat)呢?
当前回答
当向现有集合中添加多个元素(来自数组或另一个集合)时,调用new Set(…anArrayOrSet)没有任何意义。
我在reduce函数中使用了这个,它只是简单的愚蠢。即使你有…数组展开运算符可用,在这种情况下不应该使用它,因为它浪费处理器、内存和时间资源。
// Add any Map or Set to another
function addAll(target, source) {
if (target instanceof Map) {
Array.from(source.entries()).forEach(it => target.set(it[0], it[1]))
} else if (target instanceof Set) {
source.forEach(it => target.add(it))
}
}
演示片段
// Add any Map or Set to another function addAll(target, source) { if (target instanceof Map) { Array.from(source.entries()).forEach(it => target.set(it[0], it[1])) } else if (target instanceof Set) { source.forEach(it => target.add(it)) } } const items1 = ['a', 'b', 'c'] const items2 = ['a', 'b', 'c', 'd'] const items3 = ['d', 'e'] let set set = new Set(items1) addAll(set, items2) addAll(set, items3) console.log('adding array to set', Array.from(set)) set = new Set(items1) addAll(set, new Set(items2)) addAll(set, new Set(items3)) console.log('adding set to set', Array.from(set)) const map1 = [ ['a', 1], ['b', 2], ['c', 3] ] const map2 = [ ['a', 1], ['b', 2], ['c', 3], ['d', 4] ] const map3 = [ ['d', 4], ['e', 5] ] const map = new Map(map1) addAll(map, new Map(map2)) addAll(map, new Map(map3)) console.log('adding map to map', 'keys', Array.from(map.keys()), 'values', Array.from(map.values()))
其他回答
集:
var merged = new Set([...set1, ...set2, ...set3])
地图:
var merged = new Map([...map1, ...map2, ...map3])
注意,如果多个映射具有相同的键,则合并映射的值将是具有该键的最后一个合并映射的值。
编辑:
I benchmarked my original solution against other solutions suggests here and found that it is very inefficient. The benchmark itself is very interesting (link) It compares 3 solutions (higher is better): @fregante (formerly called @bfred.it) solution, which adds values one by one (14,955 op/sec) @jameslk's solution, which uses a self invoking generator (5,089 op/sec) my own, which uses reduce & spread (3,434 op/sec) As you can see, @fregante's solution is definitely the winner. Performance + Immutability With that in mind, here's a slightly modified version which doesn't mutates the original set and excepts a variable number of iterables to combine as arguments: function union(...iterables) { const set = new Set(); for (const iterable of iterables) { for (const item of iterable) { set.add(item); } } return set; } Usage: const a = new Set([1, 2, 3]); const b = new Set([1, 3, 5]); const c = new Set([4, 5, 6]); union(a,b,c) // {1, 2, 3, 4, 5, 6}
原来的答案
我想建议另一种方法,使用reduce和spread运算符:
实现
function union (sets) {
return sets.reduce((combined, list) => {
return new Set([...combined, ...list]);
}, new Set());
}
用法:
const a = new Set([1, 2, 3]);
const b = new Set([1, 3, 5]);
const c = new Set([4, 5, 6]);
union([a, b, c]) // {1, 2, 3, 4, 5, 6}
Tip:
我们还可以使用rest操作符来使界面更好:
function union (...sets) {
return sets.reduce((combined, list) => {
return new Set([...combined, ...list]);
}, new Set());
}
现在,我们不再传递一个集合数组,而是可以传递任意数量的集合参数:
union(a, b, c) // {1, 2, 3, 4, 5, 6}
将集合转换为数组,将它们平直,最后构造函数将惟一化。
const union = (...sets) => new Set(sets.map(s => [...s]).flat());
根据Asaf Katz的回答,以下是一个打字版本:
export function union<T> (...iterables: Array<Set<T>>): Set<T> {
const set = new Set<T>()
iterables.forEach(iterable => {
iterable.forEach(item => set.add(item))
})
return set
}
你可以使用spread语法将它们合并在一起:
const map1 = {a: 1, b: 2}
const map2 = {b: 1, c: 2, a: 5}
const mergedMap = {...a, ...b}
=> {a: 5, b: 1, c: 2}
推荐文章
- 检测用户何时离开网页的最佳方法?
- 当“模糊”事件发生时,我如何才能找到哪个元素的焦点去了*到*?
- React不会加载本地图像
- 如何将Blob转换为JavaScript文件
- 在另一个js文件中调用JavaScript函数
- 如何在svg元素中使用z索引?
- 如何求一个数的长度?
- 跨源请求头(CORS)与PHP头
- 如何用Express/Node以编程方式发送404响应?
- parseInt(null, 24) === 23…等等,什么?
- JavaScript变量声明在循环外还是循环内?
- 元素在“for(…in…)”循环中排序
- 在哪里放置JavaScript在HTML文件?
- 什么时候.then(success, fail)被认为是承诺的反模式?
- 从浏览器下载JSON对象作为文件