Bunyod Kh.
Bunyod Kh.

Reputation: 11

How to flatten array with the given callback in Javascript?

The function must project each element of the specified array to a sequence and flatten the resulting sequences into one array.

I have the function that must return the flattened array based on the given selector function (childrenSelector) but facing issues when applying slice() function.

When applying slice as a selector function, it says

TypeError: x.slice is not a function

function flattenArray(arr, childrenSelector) {
  return arr.reduce((accumArr, currVal) => {
      console.log(currVal);
      return Array.isArray(currVal) 
        ? accumArr.concat(currVal.map(childrenSelector)) 
        : accumArr.concat(childrenSelector(currVal))
    }, []
  );
}

flattenArray([[11, 12, 13, 14, 15], [21, 22, ,23, 24, 25], [31, 32, 34, 35]], x => x.slice(0, 2))

Is there any solution for this issue?

Upvotes: 0

Views: 603

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370729

The problem is that, when iterating over the outer array, the conditional

Array.isArray(currVal)

is fulfilled, so

accumArr.concat(currVal.map(childrenSelector))

runs when currVal is an array of numbers. But numbers don't have a .slice method.

Instead, call childrenSelector on the currVal, without .map (so that the array is sliced):

function flattenArray(arr, childrenSelector) {
  return arr.reduce((accumArr, currVal) => {
    return accumArr.concat(childrenSelector(currVal));
  }, []);
}

console.log(
  flattenArray([
    [11, 12, 13, 14, 15],
    [21, 22, , 23, 24, 25],
    [31, 32, 34, 35]
  ], x => x.slice(0, 2))
);

You can also use flatMap:

const flattenArray = (arr, childrenSelector) => arr.flatMap(childrenSelector);

console.log(
  flattenArray([
    [11, 12, 13, 14, 15],
    [21, 22, , 23, 24, 25],
    [31, 32, 34, 35]
  ], x => x.slice(0, 2))
);

Upvotes: 3

Related Questions