Создание массива, состоящего из самых больших значений каждого подмассива, не работает должным образом.

Найдите наибольшее число в каждом подмассиве, а затем создайте массив из этих самых больших чисел.[[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]

Я написал какой-то код, и я не могу понять, что с ним не так. Возможно, метод Array.push() не работает или циклы for.

function largestOfFour(arr) {
    var main = [];
    for(k=0;k<arr.length;k++){
       var long= 0;
         for(i=0;i<arr[k].length;i++){
            if(arr[k][i]<long) {
                arr[k][i] = long;
            }
            main.push[long];
        }
    }
    return main
}

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]], "");

person Lavios    schedule 20.09.2015    source источник
comment
вам нужно сбросить long для каждого цикла k ... т.е. переместить var long = 0 в начало цикла for k   -  person Jaromanda X    schedule 20.09.2015
comment
Пожалуйста, не исправляйте код в вопросе.   -  person Fernando Matsumoto    schedule 20.09.2015


Ответы (4)


Проблема во внутреннем цикле, когда вы пытаетесь найти максимальное значение для каждого массива. На каждой итерации внешнего цикла вы должны сбрасывать long = arr[k][0]. Его не следует сбрасывать на 0, так как максимальное значение может быть меньше 0. Обратите внимание, что это предполагает, что все подмассивы будут иметь хотя бы один элемент.

Как отметил @edc65, объявление long должно происходить в начале функции, чтобы было ясно, что long, как и все локальные переменные, имеет область действия функции.


Вам нужно только одно значение для каждого подмассива. Поэтому вы должны добавлять одно значение для каждой итерации внешнего цикла (main.push должно быть во внешнем цикле). В настоящее время вы добавляете одно значение для каждого элемента подмассива.


В операторе if ваше присваивание инвертируется. Должен быть

long = arr[k][i];

И условие тоже инвертированное. long хранит максимальное значение для каждого подмассива. Поэтому вы обновите его, если найдете значение больше, чем оно:

if(arr[k][i]>long) {
    long = arr[k][i];
}

При вставке в массив используйте круглые скобки, а не квадратные скобки:

main.push(long);

Круглые скобки предназначены для вызова методов. Скобки предназначены для доступа к свойствам объекта.

Окончательный код

function largestOfFour(arr) {
    var main = [];
    var long;
    for(k=0;k<arr.length;k++){
       long = arr[k][0];
         for(i=0;i<arr[k].length;i++){
            if(arr[k][i]>long) {
                long = arr[k][i];
            }
        }
        main.push(long);
    }
    return main;
}

Метод Math.max

Вы можете использовать Math.max для упрощения кода.

function largestOfFour(arr) {
    var main = [];
    for(k=0;k<arr.length;k++){
        var long = Math.max.apply(null, arr[k]);
        main.push(long);
    }
    return main;
}

Согласно @BillyMoon's и @ Tushar, это можно упростить до Array.map.

person Fernando Matsumoto    schedule 20.09.2015
comment
Я бы выбрал long = arr[k][0] вместо long = 0 при сбросе. Это будет обрабатывать случай, когда все числа отрицательные. - person Jason; 20.09.2015
comment
наличие var long... внутри for также является (незначительной) проблемой. Все локальные переменные находятся в области видимости функции и должны быть объявлены сверху. Вместо этого кажется, что long внутри for(), это не - person edc65; 21.09.2015

Я знаю, что вопрос здесь заключается в том, чтобы найти ошибку в существующем коде на случай, если вы захотите оптимизировать код.

Исходная идея принадлежит @thefourtheye. Я просто объясняю это здесь.

Нет необходимости во вложенных циклах, вы можете добиться этого в одной строке.

var arr = [[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]];

var result = arr.map(Math.max.apply.bind(Math.max, null));

document.write(result);
console.log(result);

Как это работает?

Функция array.map перебирает каждый из элементов массива, для которого она вызывается. Функция, переданная здесь map, называется apply, ее контекст this привязан к Math.max, а первый аргумент привязан к null.

Math.max.apply.bind(Math.max, null) это в основном вызывает функцию Math.max для массива как

Math.max.apply(null, array);

Обновление:

В ES6 функция стрелки и оператор расширения, его можно сделать еще меньше

arr.map(e => Math.max(...e))

var arr = [[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]];

var result = arr.map(e => Math.max(...e));

document.write(result);
console.log(result);

person Tushar    schedule 20.09.2015

Потенциально более простой метод для достижения того же результата - простота является предпосылкой надежности...

function largestOfFour(arr){
    // assumes compatible browser, or shim: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Browser_compatibility
    // map array each element into new value based on callback's return
    return arr.map(function(subarr){
        // sort to get highest value at front, and then return it
        return subarr.sort(function(a,b){
            return b-a;
        })[0];
    });
}

или с помощью Math.max (см. комментарии...)

function largestOfFour(arr){
    // assumes compatible browser, or shim: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Browser_compatibility
    // map array each element into new value based on callback's return
    return arr.map(function(subarr){
        // sort to get highest value at front, and then return it
        return Math.max.apply(null, subarr);
    });
}
person Billy Moon    schedule 20.09.2015
comment
Вы должны использовать Math.max вместо сортировки массива (как из соображений эффективности, так и из соображений неизменности) - person Bergi; 20.09.2015

Я прошел через код и закончил с другим решением. Первый цикл for проходит по большому массиву, а второй — по компонентам подмассива.

function largestOfFour(arr) {
  var main = [];
  for(k=0;k<arr.length;k++){
     var long=0;
       for(i=0;i<arr[k].length;i++){
          if(long<arr[k][i]) {
              long=arr[k][i];
          }
       }
   main.push(long);
   }
  return main;
}
person feralamillo    schedule 15.07.2016