0

I'm trying to create a map function that supports computing nested arrays, using recursion:

This function, when a unidimesional (eg. [1,2,3,4] ) array is used works fine:

const map = (oldArray, callback, newArray = []) => {

    //base case: check if there are any items left in the original array to process
    if (oldArray.length <= 0){
      //if all items have been processed return the new array
      return newArray
    } else {
      //destructure the first item from old array and put remaining in a separate array
      const [item, ...theRest] = oldArray
      // create an array of the current new array and the result of the current item and the callback function
      const interimArray = [...newArray, callback(item)]
      // return a recursive call to to map to process the next item.
      return map(theRest, callback, interimArray)
    }

  }

But, I want to support a nested array, so for example, I have an array like this:

const array = [1,[1,2],3]

and I want to apply a function, eg: (x)=>x+1;

I have this implementation so far, but I can't wrap my mind around it.

function rnMap(oldArr, fn, newArr = []) {
  const [item, ...rest] = oldArr;

  if (oldArr.length <= 0) {
    return newArr;
  } else if (Array.isArray(item)) {
    return rnMap(item, fn, [...newArr, rnMap(item, fn, [])]);
  } else {
    const interimArray = [...newArr, fn(item)];

    return rnMap(rest, fn, interimArray);
  }
}

const rnRes = rnMap(nArr, (e) => {
  return e + 1;
});

console.log(rnRes);

It returns [ 2, [ 2, 2 ], 2, 2 ] but it suppose to return [2,[2,3],4]

If anyone could help me will be appretiated. Thanks in advance.

3 Answers 3

1

No loop approach, sort of ...

const
    map = ([value, ...array], fn) => {
        if (value === undefined) return [];
        return [
            (Array.isArray(value) ? map(value, fn) : fn(value)),
            ...map(array, fn)
        ];
    },
    array = [1, [1, 2], 3],
    fn = x => x + 1;

console.log(map(array, fn));

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer but I want to use only functions, not map. I could do something like that.
Thanks for the answer but I want to use only functions, not map. I could do something like this: function nMap(arr, fn) { const newArr = []; arr.forEach((e) => { if (Array.isArray(e)) { newArr.push(nMap(e, fn)); } else { newArr.push(fn(e)); } }); return newArr; } const nArr = [1, [1, 1], 3]; const r = nMap(nArr, (e) => { return e + 1; }); but I want to do it with recursion.
Yeah! I tried something like the second answer and it works, but I wan to get rid of the for loop.
0

Finally I found the error, here is my solution:

function rnMap(oldArr, fn, newArr = []) {
  const [item, ...rest] = oldArr;

  if (oldArr.length <= 0) {
    return newArr;
  } else if (Array.isArray(item)) {
    return rnMap(rest, fn, [...newArr, rnMap(item, fn, [])]);
  } else {
    return rnMap(rest, fn, [...newArr, fn(item)]);
  }
}

const rnRes = rnMap([1, 2, [3, 4, [5, 6]], 7], (e) => {
  return e + 1;
});

console.log(rnRes);

1 Comment

Or, in a different style, const rmap = (fn) => ([x, ...xs]) => x == undefined ? [] : [Array .isArray (x) ? rmap (fn) (x) : fn (x), ...rmap (fn) (xs)]
0

This would probably be the simplest solution.

// @ts-ignore
const func = (list: Array<any>) => {
    return list.map(i => {
        if (i instanceof Array) {
            return func(i)
        }

        return i+1
    })
}

const result = func([1,[1,2],3])
console.log('log result', result)

This is in typescript, let me know if you want a js version

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.