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 come 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 comparison of keys at the end would have to be a comparison of values, which could be prohibitively expensive.
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()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With