使用JavaScript创建一组集合。

3

我有一组数组需要过滤重复项。它需要按照这样的方式工作:在每个数组内部没有重复项,在整个组中,没有两个数组持有相同的值。

第一部分很容易- 对于每个内部数组,我可以将Set 应用于该数组并进行过滤。因此,对于给定的矩阵arrays,我可以应用以下方法进行过滤:

const sets : string[][] = arrays.map(arr=>[...new Set(arr)].sort());

这将给我一个集合数组。如何将其转换为一组集合?例如,如果 sets=[[a, b],[c],[d, a],[c],[e]],我想让 setOfSets 等于 [[a, b],[c],[d, a],[e]]?

应用 setOfSets = [...new Set(sets)]; 将不起作用,因为默认情况下,即使它们具有不同的地址,相等的数组也不被视为相等。是否有一种方法来强制 set 按值进行检查,或者另一种有效的方法来创建这种效果?

编辑

原始矩阵:

[[a, b, b],
[c,c],
[b,a],
[d,a],
[c,c],
[e,e]]

创建并排序集合后:

[[a,b],
[c],
[a,b],
[d,a],
[c],
[e]]

期望的结果:

[[a,b],
[c],
[d,a],
[e]]
1个回答

4
如果你的数据集易于序列化,我会选择这样的解决方案:

const data = [
  ["a", "b", "b"],
  ["c","c"],
  ["b","a"],
  ["d","a"],
  ["c","c"],
  ["e","e"]
];

// Create the "hash" of your set
const serializeSet = s => Array
  .from(s)
  .sort()
  .join("___");

// Create a map (or object) that ensures 1 entry per hash
const outputMap = data
  .map(xs => new Set(xs))
  .reduce(
    (acc, s) => acc.set(serializeSet(s), s),
    new Map()
  );

// Turn your Map and Sets back in to arrays
const output = Array
  .from(outputMap.values())
  .map(s => Array.from(s));
  
console.log(output);

为了为您的集合设计一个好的哈希函数,您需要仔细观察您的数据。例如:
  • 当您的数组由从a到z的单个字符组成,就像我上面的示例一样,我们可以使用默认排序器对这些字符串进行sort,然后使用来自a到z范围之外的字符join结果。
  • 如果您的数组由随机字符串或数字组成,则使用JSON.stringify(Array.from(s).sort())更安全。
  • 当您的数组由普通对象组成时,您可以JSON.stringify它的排序元素,但请注意对象属性顺序的差异!(例如{a:1,b:2} vs {b:2,a:1}

1
啊,当我在打我的答案时,这些例子被添加了。谢谢提醒。我会看一下的。 - user3297291
1
我会在我的回答中添加一些示例。同时,哈希数组最常用的方法是使用JSON.stringify。也许这更有意义:serializeSet = s => JSON.stringify(Array.from(s).sort()) - user3297291
当我尝试编写这行代码(acc, s) => acc.set(serializeSet(s), s)时,我会收到错误提示property 'set' does not exist on type 'string[]'(如果我完全按照你的代码来,则是on type Set<string>)。我正在使用TypeScript - 请帮助我理解reduce函数应该做什么? - PMO1948
reduce 函数将你的包含集合的数组缩减成一个 Map 对象。这个 Map 就像是一个键和值为 string, Set 类型的字典。为了让 reduce 函数正常工作,你需要传入一个函数,该函数会将一个集合添加到 Map 中并返回它 ((acc, s) => acc.set(serialize(s), s)),还需要提供一个初始为空的 Map (new Map()).另一种方法是首先将数组转换为条目数组:const setEntries = mySets.map(s => [ serialize(s), s ]),然后使用这些条目构造一个 Mapconst uniqueSetMap = new Map(setEntries) - user3297291
我的猜测是你忘记了 reduce 的第二个参数 , new Map() - user3297291
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接