Immutable.js 集合包含重复值

Immutable.js Set contains duplicate values

我遇到了 Immutable.js' Set 的问题,根据文档,它只能包含唯一值。 此 fiddle 中的代码将导致集合中出现 2 个重复条目。

虽然此单元测试通过,但问题很可能是用户错误。

it('should only have unique object values', () => {
  const set = Set<any>();
  const newSet = set.add({ form: 'form1', name: 'control1', value: 10 });
  const finalSet = set.add({ form: 'form1', name: 'control1', value: 10 });
  expect(finalSet.count()).toBe(1);
});

谁能解释一下?

这是因为您添加的两个对象实际上是不同的对象(因此集合中的值不同),即使它们包含相同的 key/value 对。

另一个问题是您没有使用 newSet 来创建 finalSet。

如果您使用同一个对象两次,它将起作用:

it('should only have unique object values', () => {
  const set = Set<any>();
  const obj = { form: 'form1', name: 'control1', value: 10 };
  const newSet = set.add(obj);
  const finalSet = newSet.add(obj);
  expect(finalSet.count()).toBe(1);
});

您的测试用例中存在错误 - 您两次都添加到 set(而不是第二次添加到 newSet)。如果您修复此问题,则测试失败。

Immutable.js's Set uses Immutable.is to check for equality。但这并不像您预期​​的那样表现 - 它不认为不同的 JS 对象(即使具有相同的结构)是相等的:

const x = { a: 1 };
const y = { a: 1 };
console.log(Immutable.is(x, y));                                       // false

这是通过切换到不可变对象来解决的:1

console.log(Immutable.is(Immutable.fromJS(x), Immutable.fromJS(y)));   // true


1。你通常应该尽早这样做,以避免这些微妙的问题。

我完成了:

    const stuff = Immutable.List(data)
        .map(x => Immutable.fromJS(x))
        .toSet()
        .map(x => x.toJS())

我的输入是一个对象数组,并使所有对象不可变,然后该集合不再包含不完整的值。

并不是说这是一个更好的答案,事实上,我在读完这篇文章后意识到这是我需要做的。不过,这不是一个坏模式。