简体   繁体   中英

Recursive map function for nested array

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.

You could check if the value is an array and return the result of the recursive call of the function, otherwise the result of using the callback function.

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);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM