Reputation:
I need to know how to solve this problem I've read from internet.
With a given array I need find all uniques elements and minus than 10. Then do the sumatory of all of them. And later multiply each array value by this number (the sumatory).
I'm assuming I can use reduce to do the sumatory and map to multiply but I don't know really how it works and I'm stuck. Also to find the unique element is not easy.
I have the entry values and expected ones.
Input, expected
[1], [1]
[1, 1, 2], [2, 2, 4]
[0, 0, 1, 2, 1], [0, 0, 2, 4, 2]
[0, 10, 1, 1, 20, 3, 40, 3], [0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 2, 4, 11], [0, 6, 6, 12, 24, 66]
[10, 1, 1, 1], [0, 0, 0, 0]
[10, 11, 1, 2, 3, 4], [100, 110, 10, 20, 30, 40]
I'm trying a few things, but the main problem is I don't understand the syntaxis I think. I know how to solve this iterating through a loop, but I want learn by high order functions.
This is not a school project, I'm learning about this, so I don't need only the solution, I would like to understand, thanks.
What I tried is apply map like this. And also filter and reduce
var input = [0, 0, 1, 2, 1]
var output = [0, 0, 2, 4, 2]
var map, reduce, filter;
map = input.map(multiplyFunction(first,second))
function multiplyFunction(first,second){
return first*second
}
Upvotes: 4
Views: 136
Reputation: 386680
You could separate the wantes result into two parts, one for getting the factor of the unique values and another to map new values with the factor.
getSumOfUnique
The factor function iterates the values and continues for unwanted values.
This function uses an object to count seen values and takes a variable for summing the unique values.
This happens in two ways:
At the end return sum
as factor
for the calling function.
multiply
The mapping function gets the factor first and maps a new product with Array#map
.
function getSumOfUnique(array) {
let seen = {},
sum = 0;
for (const value of array) {
if (value >= 10) continue;
if (!seen[value]) {
seen[value] = 1;
sum += value;
continue;
}
if (seen[value] === 1) {
seen[value]++;
sum -= value;
}
}
return sum;
}
function multiply(array) {
const factor = getSumOfUnique(array);
return array.map(value => value * factor);
}
console.log(...multiply([1]));
console.log(...multiply([1, 1, 2]));
console.log(...multiply([0, 0, 1, 2, 1]));
console.log(...multiply([0, 10, 1, 1, 20, 3, 40, 3]));
console.log(...multiply([0, 1, 1, 2, 4, 11]));
console.log(...multiply([10, 1, 1, 1]));
console.log(...multiply([10, 11, 1, 2, 3, 4]));
Finally a functional approach by using
less10
for checking if a value is less than 10
for Array#filter
,unique
for getting only unique values by checking the index of the value for filter
as well,add
a function which adds to values, later used for Array#reduce
multiplyBy
, an IIFE (immediately-invoked function expression) with a closure over the factor, later used for map
,getArray
a function which holds all parts and mapps the array with a previously calculated factor.const
less10 = value => value < 10,
unique = (v, _, a) => a.indexOf(v) === a.lastIndexOf(v),
add = (a, b) => a + b,
multiplyBy = factor => value => factor * value,
getArray = array => array.map(multiplyBy(array
.filter(less10)
.filter(unique)
.reduce(add, 0)
));
console.log(...getArray([1]));
console.log(...getArray([1, 1, 2]));
console.log(...getArray([0, 0, 1, 2, 1]));
console.log(...getArray([0, 10, 1, 1, 20, 3, 40, 3]));
console.log(...getArray([0, 1, 1, 2, 4, 11]));
console.log(...getArray([10, 1, 1, 1]));
console.log(...getArray([10, 11, 1, 2, 3, 4]));
Upvotes: 4
Reputation: 15207
Hello and welcome to StackOverflow.
First of all, I think a good point to start to understand the syntaxis is checking the w3 examples: filter, map, reduce. Or mozilla examples: filter, map, reduce
Try these examples and try to understand each step.
Your exercise need for these three functions, so as an overview, we can define each one in this way (maybe this is so informal):
So... for your exercise.
The phrases itself explain what function to use. Check this:
I need find all uniques elements and minus than 10
It means: "I need to use filter
with a function like return unique && x < 10
."
Then do the sumatory
So... reduce to an unique element. Is like "Then do reduce
with a function like return currentValue + nextValue
And later multiply each array value by this number
That's like: "And later map every value as value*=sumatory
"
And that's all! Easy, right? Now let's translate into code.
Let's assuming you have an array like this: [10, 11, 1, 2, 3, 4]
(the last into the example)
First you need to find the unique value and < 10 using filter
.
The unique position has a trick. If you compare the first and last index for a number and it's the same value, then... is unique. So the function is like this
var array = [10, 11, 1, 2, 3, 4]
var filter = array.filter(x => (array.indexOf(x) === array.lastIndexOf(x) && x < 10))
console.log(filter) // [ 1, 2, 3, 4 ]
But there is no only one way to do this. You can create a Set
to no repeat values, count every value to get those with count=1
or whatever, is your decission. I've chosen this because I think is the best way.
The syntaxis is easy to read: For each value into the array, named x
then do =>
the function. In this case compare the index and compare is <10
.
Note that in yor example you are missing (x) =>
so you can't pass variables to your function.
Next step... reduce
var reduce = filter.reduce((a, b) => a + b, 0)
console.log(reduce) // 10
Easy. Use reduce
into the output array.
The sintaxys here is: "With the current value a
and next value b
, do =>
the function a+b
starting at 0
". In other words... do the sumatory.
The last step: Map
.
var map = array.map((m) => {
return m * reduce
})
console.log(map) // [ 100, 110, 10, 20, 30, 40 ]
Here you are saying: "For every value into the array, m
, do a function =>{...}
where multiply by the sumatory m * reduce
."
AND NOW: DO IT TOGETHER!!
Yes, the (really) last step, only replace variables for functions.
Where you see reduce
put filter.reduce((a, b) => a + b, 0)
.
And where there is filter
set array.filter(x => (array.indexOf(x) === array.lastIndexOf(x) && x < 10))
var map = array.map((m) => {
return m * (array.filter(x => (array.indexOf(x) === array.lastIndexOf(x) && x < 10))).reduce((a, b) => a + b, 0)
})
And that's all.
Hope it helps to understand a little bit how to use the functions and how to solve these problems.
After see what have you try, check the examples and note that you need to get the variables using (var) =>
.
And a snippet
var array = [10, 11, 1, 2, 3, 4]
var map = array.map((m) => {
return m * (array.filter(x => (array.indexOf(x) === array.lastIndexOf(x) && x < 10))).reduce((a, b) => a + b, 0)
})
console.log(map)
Upvotes: 3
Reputation: 141
Welcome V.D. I am a JS noob as well but this, I think I get ;)
You wanna filter out your values first, so the Array.filter method allows you to do so without any cumbersome for loops, like this:
const array = [10, 11, 3, 20, 5];
const lesserThanTen = array.filter(element => element < 10);
console.log(lesserThanTen) //[3, 5]
the syntax of the reduce() function requires you to first define the function you want to apply to the items in your array, like this:
function myFunc(total, num) {
return total + num; // this will return the sum of the two numbers it receives
}
// The reduce() method applies this to the array until it is just a single value
var reducedNumbers = lesserThanTen.reduce(myFunc);
Once ou have the filtered array and the summatory, you can proceed to multiply everything by this latter number.
var x = lesserThanTen.map(multiplyBySummatory)
This should be enough for you to get there ;)
Upvotes: 2