2016-03-29 4 views
0

Проблема лучше всего объясняется комментариями в моем коде.Как перемещать массивы разной длины с помощью JavaScript?

// Find all commonNums divisible by arr && sequential that produce a whole number quotient. 
// commonNums [ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75] 
// arr [1,5] 
// sequential [ 2, 3, 4 ] 
for (var n = 0; n < commonNums.length; n++) { 
    for (var o = 0; o < sequential.length; o++) { 
    for (var p = 0; p < arr.length; p++) { 
    if (commonNums[n] % arr[p] === 0 && commonNums[n] % sequential[o] === 0) { 
    console.log(commonNums[n]); 
}}} 
} 

Поскольку массивы имеют разную длину, просто перебор с одной петлей длиной commonNums.length производится неопределенные значениями. Моим решением было использовать 3 цикла, по одному для каждого массива.

Если общее число, деленное на arr, не имеет остатка, и если общие числа, разделенные последовательностью, не имеют остатка, тогда возвращайте это число. Для arr [1,5] первое возвращаемое число должно быть 60.

Почему это решение терпит неудачу?

+0

Какие ошибки вы видите? – Gremash

+0

Не должно ли первое возвращаемое число быть 10? В конце концов, '10% 1 == 0' и' 10% 2 == 0' – entropic

+0

У меня нет ошибки, но я получаю 10 в качестве первого числа, предложенного энтропией. 10, 10, 15, 15, 20, 20, 20, 20, 30, 30, 30, 30, 40, 40, 40, 40, 45, 45, 50, 60, 60, 60, 70, 70, 75, 75. – Observer

ответ

2

Если я правильно понимаю вашу проблему правильно, то это должно работать. Он возвращает 60, поскольку это единственное число, которое делится на каждое число в двух других массивах.

outerLoop: 
for (var n = 0; n < commonNums.length; n++) { 
    for (var o = 0; o < sequential.length; o++) { 
     for (var p = 0; p < arr.length; p++) { 
      if (commonNums[n] % arr[p] != 0 || commonNums[n] % sequential[o] != 0) { 
       continue outerLoop; 
      } 
     } 
    } 
    console.log(commonNums[n]); 
} 

Обновлено для использования lablel/continue для ускорения выполнения.

+2

Престижность для выяснения того, что он хотел - но вы могли бы действительно ускорить выполнение, добавив инструкции 'break' после' match == false' – entropic

+0

Не могли бы вы объяснить энтропий? – PencilCrate

+0

Я обновил свой ответ в соответствии с предложением энтропии. – Gremash

0

Использование 3 для циклов - это путь (только), если вам нужно сгенерировать все возможные 3-кортежи из 3-х разных массивов. (Но имейте в виду, что это не будет эффективно, если вы имеете дело с большими объемами данных)

Проблема, которую я вижу с вашим решением, состоит в том, что некоторые цифры отображаются дважды. Если вы хотите разместить их только в массиве (например, чтобы вернуть их или распечатать позже), просто проверьте, нет ли в массиве Array.indexOf(), и если не добавить его.

+0

Поскольку 'Array.indexOf()' имеет сложность 'O (n)', в худшем случае это будет 'O (m * n * p)' время и пространство, поэтому это может быть очень дорого с большими наборами данных, Я бы предложил писать в хеш, чтобы он стал «O (1)» (но все равно был бы такой же сложностью в пространстве). – axelduch

+1

Да, это действительно так. Использование объекта будет лучшим вариантом, например: http: // pastebin.com/3bpzQm5t – christophetd

0

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

function check(common, seq) { 
    return common.map(function (el) { 
    return seq.every(function (e) { 
     return el % e === 0; 
    }); 
    }) 
} 

Получить результат сравнения каждого набора массивов против commonNums ...

var out = check(commonNums, arr); 
var out2 = check(commonNums, sequential); 

... а затем отфильтровать число, когда true значения корреляции в каждом индексе.

var out3 = commonNums.filter(function (el, i) { 
    return out[i] && out2[i]; 
}); 

DEMO

Смежные вопросы