JavaScript Рефакторинг от двух до многих аргументов функций - PullRequest
0 голосов
/ 05 апреля 2020

Каждая из этих двух JavaScript функций принимает ДВА аргумента массива и возвращает ОДИН результат массива. В соответствии с ES3, как я могу переписать их так, чтобы они принимали неопределенное количество входных данных массива?

function sum(v, w) {
    for (var a = jsArray(v), b = jsArray(w), t = 0; t < a.length; t++) a[t] += b[t];
    return vbArray(a);
}

function mul(v, w) {
    for (var a = jsArray(v), b = jsArray(w), t = 0; t < a.length; t++) a[t] *= b[t];
    return vbArray(a);
}

Требуется функция odd jsArray(), поскольку обрабатываемые массивы поступают из VBA и jsArray. () преобразует их в JavaScript массивы:

function jsArray(v) {
    return new VBArray(v).toArray()
}

1 Ответ

1 голос
/ 05 апреля 2020

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

function someFunc() {
  for (var i=0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

someFunc('a', 'b', 'c');

Пример преобразованной функции sum. Помните, что это работает, если все переданные массивы имеют одинаковую длину.

function sum() {
  var arrays = [];
  
  for (var i = 0; i < arguments.length; i++) {
    arrays[i] = jsArray(arguments[i]);
  }
  
  for (var j = 1; j < arrays.length; j++) {
    for (var t = 0; t < arrays[0].length; t++) {
       arrays[0][t] += arrays[j][t];
    }
  }
  
  return vbArray(arrays[0]);
}

Обобщенное решение:

function process(concreteFunc) {
  var arrays = [];

  for (var i = 1; i < arguments.length; i++) {
    arrays.push(jsArray(arguments[i]));
  }

  for (var j = 1; j < arrays.length; j++) {
    for (var t = 0; t < arrays[0].length; t++) {
       arrays[0][t] = concreteFunc(arrays[0][t], arrays[j][t]);
    }
  }

  return vbArray(arrays[0]);
}

var sum = process.bind(null, function (a, b) {return a + b});
var mul = process.bind(null, function (a, b) {return a * b});

Решение без .bind:

function process(concreteFunc, args) {
  var arrays = [];

  for (var i = 0; i < args.length; i++) {
    arrays.push(jsArray(args[i]));
  }

  for (var j = 1; j < arrays.length; j++) {
    for (var t = 0; t < arrays[0].length; t++) {
       arrays[0][t] = concreteFunc(arrays[0][t], arrays[j][t]);
    }
  }

  return vbArray(arrays[0]);
}

function createFunc(handler) {
  return function() {
    return process(handler, Array.prototype.slice.call(arguments));
  }
}

var sum = createFunc(function (a, b) {return a + b});
var mul = createFunc(function (a, b) {return a * b});

Улучшенная версия для поддержки возможности реализации avg:

function process(concreteFunc, args) {
  var arrays = [];

  for (var i = 0; i < args.length; i++) {
    arrays.push(jsArray(args[i]));
  }

  var result = [];
  
  for (var j = 0; j < arrays[0].length; j++) {
    var items = [];
    
    for (var t = 0; t < arrays.length; t++) {
      items.push(arrays[t][j]);
    }
    
    result.push(concreteFunc(items));
  }

  return vbArray(result);
}

function createFunc(handler) {
  return function() {
    return process(handler, Array.prototype.slice.call(arguments));
  }
}

function reduce(items, handler) {
  var result = items[0];
  for (var i = 1; i < items.length; i++) {
    result = handler(result, items[i]);
  }
  
  return result;
}

var sum = createFunc(function(items) {
  return reduce(items, function (a, b) {return a + b});
});
var mul = createFunc(function(items) {
  return reduce(items, function (a, b) {return a * b});
});
var avg = createFunc(function(items) {
  return reduce(items, function (a, b) {return a + b}) / items.length;
});
...