I'm just beginning to learn JavaScript and this is a part of my Take-home exam, and the requirement is quite tricky for me.
We have many ways to counting instances of values in an object in JS, but in here I have to achieve it by calling reduce()
and return an ES6 map object.
Here is the requirement:
/**
* Takes an array of items, and returns a Map with the
* frequencies (counts) of each item in the array.
*
* Must do this by using a single call to reduce.
*
* For example,
* freqs([1, 2, 3, 2, 7, 2, 1]) returns Map {1 => 2, 2 => 3, 3 => 1, 7 => 1}
* freqs("One fish two fish red fish blue fish".split(' '))
* returns Map {"One" => 1, "fish" => 4, "two" => 1, "red" => 1, "blue" => 1}
*/
And here's my code so far:
function freqs(items) {
var map = new Map();
return items.reduce(function(allkey, key) {
if (map.has(key)) {
var value = map.get(key);
map.set(key, value++);
} else {
map.set(key, 1);
}
return map;
}, {})
}
I used debugger and found out that on map.set(key, value++)
is not overwriting the new value in the map
when it iterates. Why?
So when I input C = [1,2,3,2,7,2,1];
the output is always like this:
Map(4) {1 => 1, 2 => 1, 3 => 1, 7 => 1}
Any suggestions?
I'm just beginning to learn JavaScript and this is a part of my Take-home exam, and the requirement is quite tricky for me.
We have many ways to counting instances of values in an object in JS, but in here I have to achieve it by calling reduce()
and return an ES6 map object.
Here is the requirement:
/**
* Takes an array of items, and returns a Map with the
* frequencies (counts) of each item in the array.
*
* Must do this by using a single call to reduce.
*
* For example,
* freqs([1, 2, 3, 2, 7, 2, 1]) returns Map {1 => 2, 2 => 3, 3 => 1, 7 => 1}
* freqs("One fish two fish red fish blue fish".split(' '))
* returns Map {"One" => 1, "fish" => 4, "two" => 1, "red" => 1, "blue" => 1}
*/
And here's my code so far:
function freqs(items) {
var map = new Map();
return items.reduce(function(allkey, key) {
if (map.has(key)) {
var value = map.get(key);
map.set(key, value++);
} else {
map.set(key, 1);
}
return map;
}, {})
}
I used debugger and found out that on map.set(key, value++)
is not overwriting the new value in the map
when it iterates. Why?
So when I input C = [1,2,3,2,7,2,1];
the output is always like this:
Map(4) {1 => 1, 2 => 1, 3 => 1, 7 => 1}
Any suggestions?
Share Improve this question edited Oct 12, 2017 at 0:58 Travis Su asked Oct 12, 2017 at 0:44 Travis SuTravis Su 7092 gold badges7 silver badges18 bronze badges 22-
5
FWIW, this is a weird application of
reduce
. The correct way would be to pass the map as initial value (instead of the object literal) and rename the first argument fromallkey
tomap
. – Felix Kling Commented Oct 12, 2017 at 0:46 - @Rafael OH dude I should delete that – Travis Su Commented Oct 12, 2017 at 0:49
- You also need to do a table lookup on every iteration, asking if the map entry exists and initialize the entry to 0 otherwise, and increment every time. – Rafael Commented Oct 12, 2017 at 0:49
-
@Rafael: They are doing that.
if (map.has(key)) {
– Felix Kling Commented Oct 12, 2017 at 0:50 -
3
Hint to solve your actual problem: Look at what
value++
does (developer.mozilla/en-US/docs/Web/JavaScript/Reference/…) – Felix Kling Commented Oct 12, 2017 at 0:50
1 Answer
Reset to default 5The problem with your code is that a++
returns the value of a
before adding 1
:
var a = 1;
console.log(a++);
console.log(a);
Since Map#set
returns the map after being modified, you can simplify your code like this:
function freqs(items) {
return items.reduce(
(map, e) => map.set(e, (map.get(e) || 0) + 1),
new Map()
);
}
Alternatively, you may use the somewhat obscure and rarely seen increment operator prefix, which also increments the variable, but returns the incremented new version of it:
var a = 1;
console.log(++a);
console.log(a);
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745305484a4621682.html
评论列表(0条)