Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using reduce to compose an array of cumulative strings

I want to return something like this ['4', '42','420'] for a given number: 420

I am using reduce to accumulate the number and using the index to concat the number in the index before. First two iterations are working fine, but in the third one I am having trouble thinking how to deal with the result since it is undefined => [ '4', '42', '4,42undefined' ]

Any thoughts?

function createArrayOfTiers(num) {
  const onArray = String(num).split('') 
  onArray.reduce((acc, curr, index) => {
    if (!index) return curr
    const newAcc = [...acc, acc + curr[index -1]]
    
    return newAcc
  },[])

}
createArrayOfTiers(420)
like image 924
elisa Avatar asked Nov 27 '20 22:11

elisa


People also ask

What is the reduce () array method?

The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

Can you use reduce with strings?

We use reduce() when we need to analyze all of the elements in an array and return just a single value, it can transform the data from the array into a number, string, or an object.

How do you reduce an array of arrays?

Using the reduce method. The reduce() method executes a reducer function (a function that you provide as an argument) on each element of the array, resulting in a single output value. Here, the reducer function provided is concat() and the result is stored in an empty array.


3 Answers

If you want to collect the incremental digits of a number, I think a clearer approach would be to use .map (or Array.from) instead: on each iteration, slice the (stringified) number from index 0 to the current index.

function createArrayOfTiers(num) {
  const strNum = String(num);
  return [...strNum].map((_, i) => strNum.slice(0, i + 1));
}
console.log(createArrayOfTiers(420));

To fix your existing code, you'll want to access the previous element of the accumulator, not the previous element of curr (which doesn't really make sense), multiply it by 10, and add to it the digit being iterated over. Also make sure to return the constructed array:

function createArrayOfTiers(num) {
  const onArray = String(num).split('')
  return onArray.reduce((acc, curr, index) => {
    if (!index) return Number(curr);
    return [...acc, acc[index - 1] * 10 + Number(curr)];
  }, [])
}
console.log(createArrayOfTiers(420));
like image 71
CertainPerformance Avatar answered Oct 19 '22 22:10

CertainPerformance


You have the error because you forgot to take first number in the third iteration. You take acc + curr[index - 1] but forgot about acc + curr[index - 2].

To fix it you can slice numbers from first to current and then join them.

function createArrayOfTiers(num) {
  const onArray = String(num).split("");
  return onArray.reduce((acc, curr, index, arr) => {
    const newAcc = [...acc, arr.slice(0, index + 1).join("")];

    return newAcc;
  }, []);
}
console.log(createArrayOfTiers(420));
like image 40
RukkiesMan Avatar answered Oct 19 '22 22:10

RukkiesMan


Try this:

function createArrayOfTiers(num) {
  const str = String(num);
  const res = str.split('').reduce((acc, curr, index) => {
    acc = [...acc, str.substring(0,index)+curr];
    return acc;
  }, []);
  return res;
}

console.log( createArrayOfTiers(420) );
like image 1
Majed Badawi Avatar answered Oct 19 '22 22:10

Majed Badawi