Разрезать на куски и усреднить (уменьшить) массив в JS - PullRequest
0 голосов
/ 03 мая 2018

У меня есть массив:

var data = [0,1,2,3,4,5];

, который я хотел бы разделить на [0,1,2] и [3,4,5] с последующим усреднением так, чтобы окончательный результат был:

var dataOptimised = [1,4];

вот что я нашел до сих пор:

function chunk (arr, len) {

    var chunks = [];
    var i = 0;
    var n = arr.length;

    while (i < n) {
      chunks.push(arr.slice(i, i += len)); // gives [[0,1,2] [3,4,5]]
    }

    return chunks;

};

Как уменьшить?

Спасибо

Ответы [ 6 ]

0 голосов
/ 03 мая 2018

Соглашаясь как с Ори Дрори, так и с Эдди, но я подумал, что мог бы также внести некоторые незначительные изменения в вашу chunk функцию для согласованности и удобства обслуживания ...

При написании JavaScript я бы рекомендовал использовать имена функций, которые не будут конфликтовать с общими / ожидаемыми именами переменных. Например, с такой функцией, как chunk(), которая возвращает «чанк», вполне вероятно, что вы захотите создать переменную с именем chunk для хранения ее возвращаемого значения. Строка кода, подобная var chunk = chunk(), является очевидной проблемой, но если она становится менее прямой, она может легко нанести ущерб. Использование шаблона const var = function (см. Фрагмент) поможет вам избежать перезаписи исходной функции, выдавая ошибку в правильной строке, но я бы сказал, что все же хорошо иметь привычку использовать соглашение об именах, которое не имеет этот недостаток на тот случай, если вы не можете использовать что-то вроде const. Мой подход заключается в том, чтобы всегда включать глагол в имя функции. В вашем случае «чанк» также можно рассматривать как глагол, но он конфликтует. Итак, я поставил перед ним «get».

const getChunk = (arr, len) => {
    const chunks = []
    const n = arr.length
    let i = 0

    while (i < n) {
      chunks.push(arr.slice(i, i += len))
    }

    return chunks
}

const data = [0,1,2,3,4,5]

const optimizedData =
  getChunk(data, 3).map(chunk =>
    chunk.reduce((total, val) => total + val) / chunk.length
)

console.log(optimizedData)
0 голосов
/ 03 мая 2018

Если вы не возражаете против использования underscore.js , вы можете использовать функцию _.chunk() для легкого разбиения массива на части, а затем map() каждого фрагмента в функцию reduce(), которая усредняет каждый фрагмент .

При импорте библиотеки underscore.js вы можете ссылаться на библиотеку, используя символ _.

const arr = [0, 1, 2, 3, 4, 5];
const len = 3;

const result = _.chunk(arr, len).map(chunk => chunk.reduce((a, b) => a + b, 0) / chunk.length);
console.log(result); // Outputs [1, 4]

Если у вас есть массив нечетной длины; скажем, что arr = [0, 1, 2, 3, 4, 5, 6], тогда result будет [1, 4, 6].

В HTML вы можете включить библиотеку в тег <script>:

<script src="http://underscorejs.org/underscore.js"></script>

Вот рабочий jsfiddle , где вы можете увидеть его в действии (вам придется открыть инструменты F12, чтобы увидеть вывод консоли; встроенные фрагменты StackOverflow довольно прикольные и работают неправильно) .

0 голосов
/ 03 мая 2018

Вот самый верный ответ на этот вопрос. n - это индекс, из которого вы хотите нарезать.

function chunk (arr, n) {
   return [Math.sum.apply(null, arr.slice(0, n)), Math.sum.apply(null, arr.slice(n, arr.length))];
};
0 голосов
/ 03 мая 2018

Разбить массив пополам, используя splice. И используйте .reduce, чтобы взять сумму и усреднить окончательно

var arrR = [0, 1, 2, 3, 4, 5],
    arrL = arrR.splice(0, Math.ceil(arrR.length / 2)),
    results = [getAverave(arrL), getAverave(arrR)];
console.log(results)

function getAverave(arr) {
    return arr.reduce(function(a, b) {
        return a + b;
    }) / arr.length;

}
0 голосов
/ 03 мая 2018

Вы можете map массив и reduce его.

function chunk(arr, len) {
  var chunks = [];
  var i = 0;
  var n = arr.length;

  while (i < n) {
    chunks.push(arr.slice(i, i += len)); // gives [[0,1,2] [3,4,5]]
  }

  return chunks;
};

var data = [0, 1, 2, 3, 4, 5];

var result = chunk(data, 3).map(o => (o.reduce((c, v) => c + v, 0)) / o.length);

console.log(result);
0 голосов
/ 03 мая 2018

Суммируйте каждый кусок, используя Array.reduce() и делите на averageBy. Получите averageBy, используя оператор остатка , если остаток равен 0, используйте вместо него len.

var data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30];

function chunkAverage(arr, len) {
    var chunks = [];
    var i = 0;
    var n = arr.length;
    
    var chunk;

    while (i < n) {
      chunk = arr.slice(i, i += len);
      chunks.push(
        chunk.reduce((s, n) => s + n) / chunk.length
      );
    }

    return chunks;
};

console.log(chunkAverage(data, 3));
...