Filling the empty part of an array, the functional way in Javascript

I have a function fill defined here:

/*
  Takes an Array `array` containing null values, and return a copy of that array, filled with the values in `nArray`:

  Usage:
    fill(
      [1, 2, 3],
      [null, 4, null, 5, null]
    )
    // => [1, 4, 2, 5, 3];
*/
const fill = (nArray, array) => {
  let i = 0;
  return array.map((e) => !e ? nArray[i++] : e);
}

The counter i is defined with let and is not immutable, so this code is not purely functional. How would you design this function so it becomes purely functional ?

Answers


Just make use of shift :

const fill = (nArray, array) => {
  return array.map((e) => !e ? nArray.shift() : e);
}

EDIT :

Note also, that you will have to check that nArray is not empty, for example :

(!e && nArray.length > 0) ? nArray.shift() : e

Unless you expect map to be some weird function (not the typical Array.prototype one) where that impure callback would cause havoc, your code is totally fine. i is not observable from the outside world, which makes your function pure.

If you want to avoid all mutation at any cost, you should basically go for a recursive approach:

const fill = (nArray, array) =>
  array.length
  ? array[0] 
    ? [array[0]].concat(fill(nArray, array.slice(1)))
    : [nArray[0]].concat(fill(nArray.slice(1), array.slice(1)))
  : []

(which is horribly inefficient of course, given JavaScript's lack of cons lists)

You can also use a more declarative implementation of the same thing:

const fill = (nArray, array) => {
  if (!array.length) return [];
  const [a, ...as] = array;
  if (a) return [a, ...fill(nArray, as)];
  const [b, ...bs] = nArray;
  return [b, ...fill(bs, as)];
};

Need Your Help

Problem with WPF Data Binding Defined in Code Not Updating UI Elements

c# wpf data-binding inotifypropertychanged

I need to define new UI Elements as well as data binding in code because they will be implemented after run-time. Here is a simplified version of what I am trying to do.

Download file using ajax and webservice

javascript ajax web-services

There is this 3rd party webservice. One of the public webmethods available is a GetDocument() method. This method returns a Document object. The Document object has properties for File(byte[]),