在JavaScript中获取不同的集合集
因为我有一个解决方案,我最终得到了这种类型的结构:在JavaScript中获取不同的集合集,javascript,Javascript,因为我有一个解决方案,我最终得到了这种类型的结构: let structure = new Set([ new Set(["1", "42"]), new Set(["42"]), new Set(["1", "42"]) ]); 起初,我天真地期望上述情况与此相当: let expected = new Set([ new Set(["1", "42"]), new Set(["42"]) ]); 但这并没有发生,因为结构中的第1组和第3组是不同的对
let structure = new Set([
new Set(["1", "42"]),
new Set(["42"]),
new Set(["1", "42"])
]);
起初,我天真地期望上述情况与此相当:
let expected = new Set([
new Set(["1", "42"]),
new Set(["42"])
]);
但这并没有发生,因为结构中的第1组和第3组是不同的对象,所以外部组不会消除重复
请注意,实际上我有200个集合,所有集合都包含1到10个项目,因此解决方案的执行必须得体
我能够使用在最前沿浏览器(如Chrome63+)中工作的任何现代JS,如果可能的话,我更愿意使用普通JavaScript
如果以结构或其内部数组为起点,那么使用两个不同的集合获得预期的结果的有效方法是什么?要识别重复项,可以使用lodash,或者实现等效的isEqual()
函数来比较两个集合(见下文)
将其与一个函数相结合,向最终结果集中添加不同的集合
let structure = new Set([
new Set(["1", "42"]),
new Set(["42"]),
new Set(["42", "1"])
]);
function isEqual(set1, set2) {
let s1 = Array.from(set1).sort();
let s2 = Array.from(set2).sort();
if (s1.length != s2.length)
return false;
for (let i = 0; i < s1.length; i++)
if (s1[i] !== s2[i])
return false;
return true;
}
let outerSetArray = Array.from(structure);
let deduplicated = outerSetArray.reduce((aggregator, innerSet) => {
if (!aggregator.some(s => isEqual(s, innerSet)))
aggregator.push(innerSet);
return aggregator;
}, []);
let结构=新集合([
新组([“1”,“42”]),
新设置([“42”]),
新设置([“42”,“1”])
]);
函数相等(set1,set2){
设s1=Array.from(set1.sort();
设s2=Array.from(set2.sort();
如果(s1.长度!=s2.长度)
返回false;
for(设i=0;i{
如果(!aggregator.some(s=>isEqual(s,innerSet)))
聚合器。推送(内部集);
返回聚合器;
}, []);
现在,deduplicated deleted
是一组不同的集合,如果需要,您可以将其转换回集合 这可能有点贵,但可以完成工作。我不确定这在计算上会得到多少不希望的结果
策略1:
- 使用
JSON.stringify
创建带有字符串化数组的集合
- 使用
JSON.parse
将集合元素转换回数组
策略2:
- 创建值为“-”连接字符串的对象
- 通过映射键并用“-”分隔符拆分来重建数组
//JSON STRINGIFY-JSON解析策略
让结构=新集合([
新组([“1”,“42”]),
新设置([“42”]),
新设置([“1”,“42”])
]);
const json_stringify_set=新集合([…结构].map(a=>json.stringify([…a]))
const json_parsed_set=新集([…json_stringized_set].map(a=>json.parse(a)))
log([…json_parsed_set]);
//精简对象策略
const reduced_object=[…structure]。reduce((a,b)=>{a[…b]。join(“-”)=”;返回a},{})
const final_set=new set(Object.keys(reduced_Object.map)(a=>a.split(“-”))
console.log([…最终设置])
因此,我们可以:
const result = new Set(filterUniqueSets(
new Set(1,2,3),
new Set(1,3,4)
));
也许你可以用这样的方式:
功能相同(val1,val2){
var v1、v2、s;
if(阵列的val1实例和阵列的val2实例){
var l=val1.1长度;
如果(l!==val2.长度){
返回false;
}
for(var i=0;我感谢你的回答。我已经澄清了我的问题,不会使你的答案无效,但我确实添加了我实际上想要的是一个普通的JS解决方案。@Jeroen明白了!用一个普通的解决方案更新了它。顺便说一句,在你的回答中,我会用聚合器更改聚合器。过滤器(…)。长度==0
,只使用聚合器。一些(…)
@Jeroen酷主意!完成。@Jeroen如果有任何答案解决了您的问题,请继续接受您最喜欢的解决方案。干杯!啊..是的…我承认我确实求助于。这当然比什么都没有好,但我曾希望有一种更干净、更快的做事方式…@Jeroen请检查我最新的答案。使用e reduce strategy?再次感谢您甚至添加了其他选项。reduce strategy与我分享了一些想法,并且看起来更好,尽管相对的缺点是您必须选择一个在输入中没有出现的连接/拆分字符串。但它肯定适用于我的情况。我有点困惑,没有看到任何与Set其中的对象?只是一个帮助函数,这样你就可以互相测试对象或数组。没有时间获得更多帮助。抱歉。Thx!很好的简洁解决方案,可能是我可以用于AoC的,我知道输入。但是如果你有未知的输入,可能包含你加入的字符串,这就有点棘手了。@jeroen这两种方法都有速度慢或者有这么小的缺点
const result = new Set(filterUniqueSets(
new Set(1,2,3),
new Set(1,3,4)
));