【问题标题】:Iterating over every pair of elements in a Map遍历 Map 中的每一对元素
【发布时间】:2019-08-28 13:37:17
【问题描述】:

我有一个 Map,其中包含 Shape 对象值,其 id 作为键。 我需要迭代此地图中的每一对形状,但我只想对每一对形状进行一次迭代。

我知道我可以使用 forEach 或 for..of,但我找不到防止重复对的方法。此外,这应该尽可能高效。

shapes.forEach((shape1, shapeId1) => {
    shapes.forEach((shape2, shapeId2) => {
        // iterating over each pair many times
    });
});

【问题讨论】:

  • 你觉得普通的for循环怎么样?还是需要使用forEach()之类的方法?
  • 我需要保留地图的功能以允许我按 id 访问形状(形状被删除并添加到 id 不是连续的)
  • 您应该能够保留您的Map,即使您迭代其entries() 输出。但是,为什么您的地图将对象作为 keys 而将 ids 作为 values?如果要通过 id 查找对象,id 应该是 key,object 应该是 value。
  • 你说得对,我不小心在 key 和 value 之间切换了。 (编辑原帖)
  • 好的,我将更改我的答案以匹配它(您应该在您的问题中将(shape1, shapeId1) 更改为(shapeId1, shape1),同样使用2

标签: javascript arrays typescript object


【解决方案1】:

我建议首先将 Map 转换为其条目数组:

const entryArray = Array.from(shapes.entries());

然后您可以选择通过传统的for 循环来迭代对:

console.log("FOR LOOP");
for (let i = 0; i < entryArray.length; i++) {
  const [shapeId1, shape1] = entryArray[i];
  for (let j = i + 1; j < entryArray.length; j++) {
    const [shapeId2, shape2] = entryArray[j];
    console.log(shapeId1, shapeId2);
  }
}

或者通过函数forEach数组方法:

console.log("FOREACH");
entryArray.forEach(([shapeId1, shape1], i) =>
  entryArray.slice(i + 1).forEach(([shapeId2, shape2]) => {
    console.log(shapeId1, shapeId2);
  })
);

在每种情况下,您都在通过内部循环避免重复,只在外部循环索引之后迭代元素。我不知道您的 Shape 或 id 类型是什么样的,但鉴于此:

interface Shape {
  area: number;
}

const shapes: Map<string, Shape> = new Map([
  ["a", { area: 1 }],
  ["b", { area: 2 }],
  ["c", { area: 3 }]
]);

以上代码输出

FOR LOOP
a b
a c
b c
FOREACH
a b
a c
b c

所以你可以看到你得到了不同的对。希望有帮助;祝你好运!

Link to code

【讨论】:

    【解决方案2】:

    您可以使用两个用于使用索引的迭代,并从根索引 + 1 开始嵌套迭代。这将确保您永远不会处理两个对。

    const arr = [1,2,3,4];
    
    
    for (let i = 0; i<arr.length-1; i++) {
      for (let j = i+1; j<arr.length; j++) {
        console.log(`${arr[i]} - ${arr[j]}`)
      }
    }
    

    【讨论】:

    • 这是我正在寻找的结果,但我有一个地图,而不是一个数组。
    • 您可以将地图转换为数组:const arr = Array.from(myMap.values())
    【解决方案3】:

    使用带有两个索引的 Set:

    let indexes = new Set();
    
    shapes.forEach((shape1, shapeId1) => {
    
        shapes.forEach((shape2, shapeId2) => {
    
            if (set.has(`${shapeId1}-${shapeId2}`) || set.has(`${shapeId2}-${shapeId1}`)) return;
            set.add(`${shapeId1}-${shapeId2}`);
    
        });
    
    });
    

    【讨论】:

    • 这仍然会在每一对上运行不止一次
    • 修复了@Guy,现在更好了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 2020-04-07
    相关资源
    最近更新 更多