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 badges3 Answers
Reset to default 6You 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
评论列表(0条)