Создание функции, которая объединяет все элементы из N массивов, используя команду apply.

1

Я занимаюсь функциями более высокого порядка, фактически строгая кодировка того, что происходит под капотом. Я не понимаю этих вопросов, потому что у меня очень ограниченное понимание того, как применяются методы() и аргументы.

Это мой ожидаемый результат:

mapN([1, 2, 3], [4, 5, 6], [2, 2, 2], function(a, b, c) {
  return (a * b) + c;
});
// => [6, 12, 20]

mapN([1, 2, 3], function(x) { return x * x; }) // => [1, 4, 9]

Я вручную закодировал функцию forEach и функцию Map, подобную этой (я знаю, что это не обязательно, но я пытаюсь по-настоящему понять, что происходит под капотом с HOF):

function each(coll, f) {
  if (Array.isArray(coll)) {
    for (var i = 0; i < coll.length; i++) {
      f(coll[i], i);
    }
  } else {
    for (var key in coll) {
      f(coll[key], key);
    }
  }
}

function map(array, f) {
  var acc = [];
  each(array, function(element, i) {
    acc.push(f(element, i));
  });
  return acc;
}

Однако я понятия не имею, куда идти отсюда. Как использовать атрибуты apply и arguments вместе? Я потратил час, пытаясь понять это? :

function mapN(f){
  var newArray = [];
  var args = Array.prototype.slice.apply(arguments);
  f.apply(newArray, args)
  return newArray;
}
  • 0
    Вы используете / определяете mapN, как если бы оно имело 3 разных подписи; что это?
  • 0
    @ScottHunter два из них являются примерами того, что, если следует обрабатывать
Теги:
arguments
prototype
apply
higher-order-functions

1 ответ

1

Вы должны пропустить все массивы для создания массива параметров, который вы будете использовать для apply:

function mapN () {
    var args = Array.from(arguments),                         // arguments passed to 'mapN'
        callback = args.pop(),                                // the callback function is the last argument
        result = [];                                          // the result array

    if(!args.length) return result;                           // if there is no arrays passed as arguments, then return the empty array

    for(var i = 0, len = args[0].length; i < len; i++) {      // for each i from 0 to the length of one of the arrays
        var params = args.map(arr => arr[i]);                 // get the i-th element of every array in args to use as parameters to the callback
        result.push(callback.apply(null, params));            // call the callback with the params array and store the result
    }
    return result;
}

Примечание: если массивы могут иметь разную длину, вы можете изменить:

len = args[0].length

чтобы:

len = Math.max.apply(null, args.map(arr => arr.length));

поэтому len будет равна максимальной возможной длине.

Примеры:

function mapN () {
    var args = Array.from(arguments),
        callback = args.pop(),
        result = [];

    if(!args.length) return result;

    for(var i = 0, len = args[0].length; i < len; i++) {
        var params = args.map(arr => arr[i]);
        result.push(callback.apply(null, params));
    }
    return result;
}

var a = mapN([1, 2, 3], [4, 5, 6], [2, 2, 2], function(a, b, c) {
    return (a * b) + c;
});
console.log(a);
// => [6, 12, 20]

var b = mapN([1, 2, 3], function(x) { return x * x; });
console.log(b);
// => [1, 4, 9]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню