Уменьшить многомерный массив, чтобы получить sum / avg / min / max заданного массива

#javascript

#javascript

Вопрос:

У меня есть массив следующим образом:

a = [[1,2,3,4],[5,6,7,8]]

Я хочу уменьшить его таким образом, чтобы в соответствии с функцией пользовательского ввода f(array,ops) он должен выводить результат следующим образом:

result = f(a,"sum"):
result = [6,8,10,12]

 const methods = {
        sum: (arr) => arr.reduce((total, v) => total   v, 0),
        avg: (arr) => methods.sum(arr) / arr.length,
        max: (arr) => Math.max.apply(null, arr),
        min: (arr) => Math.min.apply(null, arr),
      };
  

Описанным выше способом я планирую использовать его как:
methods[methodname(array)];

Я хочу вызывать методы, как показано ниже:

 const value = Array(a.length);
a.forEach((elem,ind) => {
 value[0] = methods["sum"] // for all elem[0]
 value[1] = methods["sum"] // for all elem[1]
});
  

но мне нужно передать это для многомерного массива. Может кто-нибудь предложить способ сделать это?

Ответ №1:

Вам нужно транспонировать массив и сопоставить его с одной из ваших функций.

 const
    transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
    f = (array, key) => array
        .reduce(transpose, [])
        .map(methods[key]),
    methods = {
        sum: arr => arr.reduce((total, v) => total   v, 0),
        avg: arr => methods.sum(arr) / arr.length,
        max: arr => Math.max(...arr),
        min: arr => Math.min(...arr),
    },
    a = [[1, 2, 3, 4], [5, 6, 7, 8]];

console.log(...f(a, "sum")); // [6, 8,1 0, 12]
console.log(...f(a, "avg"));  

Комментарии:

1. О, вау, большое вам спасибо, это то, чего я хотел!!!

Ответ №2:

Функция накопителя в вашем reduce должна иметь дело с внутренним массивом.

 var a = [[1, 2, 3], [4, 5, 6]]

function sum(a) {
  return a.reduce((v, current) => {
    if (!v) return current.slice();
    for (let i = 0; i < v.length; i  )
      v[i]  = current[i];
    return v;
  }, undefined);
}

function avg(a) {
  return sum(a).map(x => x / a.length)
}

function max(a) {
  return a.reduce((v, current) => {
    if (!v) return current.slice();
    for (let i = 0; i < v.length; i  )
      if (current[i] > v[i]) v[i] = current[i];
    return v;
  }, undefined);
}

function min(a) {
  return a.reduce((v, current) => {
    if (!v) return current.slice();
    for (let i = 0; i < v.length; i  )
      if (current[i] < v[i]) v[i] = current[i];
    return v;
  }, undefined);
}
console.log(sum(a))
console.log(avg(a))
console.log(max(a))
console.log(min(a))