wakkuwakku
wakkuwakku

Reputation: 31

Returning from Array.prototype.map() is not consistent

I'm trying to get this output ['1', '12', '123'] from:

   getSubstrings('123');

   function getSubstrings(string) {
      let array = string.split('');
      let subarray = [];
      return array.map(element => {
        subarray.push(element);
        console.log(subarray)       //this gets me ['1'], then ['1','2'] ...
        return subarray;            //but this is not returning the same as in console.log(subarray)   
      });
      
    }

I know I can get the result I want by adding .join('') to the end of subarray. My question is not about how to get ['1', '12', '123'] But, why returning the same subarray as the one being outputted on the console would result in [[1','2','3'], ['1','2','3'], ['1','2','3']] instead of [[1], [1,2], [1,2,3]] weird enough, the output from the console.log(subarray) is not the same as the returning subarray populated in the .map() Am I missing something here? Thanks in advance.

Upvotes: 2

Views: 155

Answers (2)

Ran Turner
Ran Turner

Reputation: 18016

Notice that the subarray is being modify in every iteration and is not creating a new subarray. so what it actually happening is that you're passing the exact same reference to return, hence resulting in changing all results.

I suggest to refactor this to use forEach, something like this:

   const arr = getSubstrings('123');

   function getSubstrings(string) {
      let array = string.split('');
      let mainArray = [];
      let cur = '';
      array.forEach(x => {
         cur += x;
         mainArray.push(cur);
      })
      return mainArray;
    }
    
    console.log(arr)     

Upvotes: 1

testing_22
testing_22

Reputation: 2585

The problem is that subarray is changing in each map 'iteration', because you are not creating a new subarray, just passing the same reference to return. It will change all the three cases.

First, it returns [1], but then it returns [1,2] and change the first to [1,2]. Same happens with last element. Finally, you'd have an array made by three copies of the same reference (subarray).

Fix it by the spread operator

function getSubstrings(string) {
      let array = string.split('');
      let subarray = [];
      return array.map(element => {
        subarray.push(element);
        return [...subarray].join(""); // join to get the desired output  
      });
    }

console.log(getSubstrings("123"))

Upvotes: 1

Related Questions