ES6地图中的所有对

时间:2016-10-15 20:59:28

标签: javascript ecmascript-6

在ES6中,给定一个Map,如何访问一对值,哪个顺序不重要?

如果这是数组,我会这样做:

let arr = ["a", "b", "c", "d"];

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

使用地图,我很难找到一种方法,以高效和优雅的方式做类似的事情。迭代器看起来像他们会这样做,但我假设他们的行为类似于C ++标准库迭代器,其中迭代器可以克隆到独立的迭代器中。

我提出的最好的是:

var map = new Map([[0, "a"],[1, "b"],[2, "c"],[3, "d"]]);

for (let key of map.keys()) {
  let log_away = false;

  for (let other_key of map.keys()) {
    if (log_away)
        console.log(`${map.get(key)},${map.get(other_key)}`);
    else
        log_away = (key === other_key);
}

这是相当简洁的,但不管是否使用,必须访问所有对,都难以实现。更糟糕的是,如果要尝试将其调整为包含大型对象的Set,则最后的键的比较必须是值的比较,这可能非常昂贵。

3 个答案:

答案 0 :(得分:6)

您可以调用values()方法,然后在结果上调用Array.from()以获取所有值的数组。然后你可以像对数组那样做。

&#13;
&#13;
const map = new Map([[0, "a"],[1, "b"],[2, "c"],[3, "d"]])

const values = Array.from(map.values())
for (let i = 0; i < values.length; i++)
  for (let j = i + 1; j < values.length; j++)
    console.log(`${values[i]},${values[j]}`)
&#13;
&#13;
&#13;

答案 1 :(得分:2)

为混音添加一个循环选项(不是更好,只是替代方案):使用rest运算符始终循环其余条目。

&#13;
&#13;
let map = new Map([[0, "a"],[1, "b"],[2, "c"],[3, "d"]]);

let arr = [...map.values()] ,v;
while(arr.length > 1){
  [v,...arr] =arr;  
  arr.forEach(v2 => console.log([v,v2].join(',')));
}
&#13;
&#13;
&#13;

或在递归函数(变量)中执行相同操作以获取对数组:

&#13;
&#13;
let map = new Map([[0, "a"],[1, "b"],[2, "c"],[3, "d"]]);

const fn = ([v,...a]) => v ? [...a.map(v2=>[v,v2].join()),...fn(a)] : [];
console.log(fn(map.values()));
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以结合使用Array.frommap.values()some来创建此ES6解决方案:

var map = new Map([[0, "a"],[1, "b"],[2, "c"],[3, "d"]]);

Array.from(map.values()).forEach( ([key1], i, a) =>
    a.some( ([key2], j) => i !== j ? console.log(key2, key1) : true )
);

这使用console.log不返回值的事实,因此必须注意在更实际的应用程序中重用它。因此,在数组中收集对可能更有用,然后可以将其用于以后的处理:

注意:使用点差运算符当然是Array.from的替代选择:

var map = new Map([[0, "a"],[1, "b"],[2, "c"],[3, "d"]]);

var pairs = [...map.values()].reduce( (acc, [key1], i, a) =>
    (a.some( ([key2], j) => i === j || !acc.push([key2, key1]) ), acc), []
);
console.log(pairs);