javascript - All pairs in an ES6 Map - Stack Overflow

In ES6, given a Map, how would one visit pairs of values, where order is unimportant?If this were array

In ES6, given a Map, how would one visit pairs of values, where order is unimportant?

If this were arrays, I would do as follows:

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]}`);

With Maps, I'm struggling to find a way to do something similar in an efficient and elegant manner. Iterators looked like they would do the trick, but I was assuming they would behave like C++ Standard Library iterators, where an iterator can be cloned into independent iterators.

The best I've e up with is:

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);
}

This is reasonably succinct, but having to visit all pairs, whether they will be used or not, is hardly efficient. Worse, if one were to try to adapt this to a Set containing large objects, the parison of keys at the end would have to be a parison of values, which could be prohibitively expensive.

In ES6, given a Map, how would one visit pairs of values, where order is unimportant?

If this were arrays, I would do as follows:

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]}`);

With Maps, I'm struggling to find a way to do something similar in an efficient and elegant manner. Iterators looked like they would do the trick, but I was assuming they would behave like C++ Standard Library iterators, where an iterator can be cloned into independent iterators.

The best I've e up with is:

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);
}

This is reasonably succinct, but having to visit all pairs, whether they will be used or not, is hardly efficient. Worse, if one were to try to adapt this to a Set containing large objects, the parison of keys at the end would have to be a parison of values, which could be prohibitively expensive.

Share Improve this question edited Oct 15, 2016 at 21:10 Michał Perłakowski 92.9k30 gold badges163 silver badges188 bronze badges asked Oct 15, 2016 at 20:59 MarkMark 434 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

You can call the values() method and then call Array.from() on the result to get an array of all the values. Then you can do it as you do with arrays.

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]}`)

To add one more loop option to the mix (not better, just an alternative): using the rest operator to always loop through the remaining entries.

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(',')));
}

or do the same in a recursive function (variable) to get an array of pairs:

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()));

You could bine the use of Array.from, map.values() and some to create this ES6 solution:

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 )
);

This uses the fact that console.log does not return a value, so care has to be taken to reuse this in a more practical application. It might therefore be more useful to gather the pairs in an array, which can then be used for processing later:

NB: Use of the spread operator is of course an alternative for 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);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745138948a4613338.html

相关推荐

  • javascript - All pairs in an ES6 Map - Stack Overflow

    In ES6, given a Map, how would one visit pairs of values, where order is unimportant?If this were array

    4小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信