2017-02-12 3 views
1

Ниже я представил два фрагмента кода, которые, на мой взгляд, должны делать то же самое. В первом фрагменте я получаю «нулевое» значение. Я предполагаю, что это связано с тем, что значение null передается в функцию как arr, когда я вызываю steamrollArray(arr[0]) на [], нажимая нулевое значение в аккумулятор.Нулевое значение в рекурсии с выравниванием массива с использованием `for` vs` slice`: почему результаты этих двух функций различны?

То, что я не знаю, и я надеюсь, что смогу помочь, может быть, это элегантный способ избежать этой конкретной проблемы?

Я хотел бы, чтобы обе функции выдавали одинаковый выход при задании одного и того же входа.

В качестве вспомогательного пункта: мне было бы интересно узнать, может ли кто-нибудь указать мне метод проверки этих двух методов друг против друга - об этом я ничего не знаю, кроме того, что это «вещь» , и мне было бы полезно понять, как это сделать, и конкретно, как это можно сделать с этой проблемой.

В качестве другой вспомогательной точки: существует ли интерактивный интерпретатор javascript, так же как вы можете получить интерактивный интерпретатор python (где вы можете играть/проверять вещи в командной строке)?

Версия 1: "естественный" рекурсии - возвращает [1,null,2,3]

function steamrollArray(arr) { 
 
    // I'm a steamroller, baby 
 
    //recursive (is an array) 
 
    var accum = []; 
 
    if (Array.isArray(arr)) { 
 
    accum = accum.concat(steamrollArray(arr[0])); 
 
    if (arr.length > 1) { 
 
     accum = accum.concat(steamrollArray(arr.slice(1))); 
 
    } 
 
    } else { 
 
    accum.push(arr); 
 
    } 
 
    return accum; 
 
} 
 

 
console.log(
 
    steamrollArray([1, [], [3, [[4]]]]) 
 
);

Вариант 2: for цикл рекурсии - возвращает [1,2,3]

function steamrollArray(arr) { 
 
    // I'm a steamroller, baby 
 
    //recursive (is an array) 
 
    var accum = []; 
 
    for (var i = 0; i < arr.length; i++) { 
 
    if (Array.isArray(arr[i])) { 
 
     accum = accum.concat(steamrollArray(arr[i])); 
 
    } else { 
 
     accum.push(arr[i]); 
 
    } 
 
    } 
 
    return accum; 
 
} 
 

 
console.log(
 
    steamrollArray([1, [], [3, [[4]]]]) 
 
);

+1

«Есть ли интерактивный интерпретатор javascript *» - вы пытались нажать 'F12' в своем браузере? ':)' (В Chrome вам может понадобиться щелкнуть вкладку «Консоль».) – apsillers

+0

@apsillers именно то, что я искал, спасибо! Я знал, что в хроме должна быть такая особенность. – NotAnAmbiTurner

ответ

3

В версии 1 Вы выдвигаете arr[0] без проверки, если есть элемент внутри arr[0]. Таким образом, при втором вызове steamrollArray где вы передаете пустой массив [], arr[0] будет неопределенным:

var arr = []; 
 

 
console.log(arr[0]);

Почему это не происходит в версии 2? Это потому, что у вас есть петля for, обертывающая вызовы push (for(var i = 0; i < arr.length...). Поэтому, когда пустой массив передается, цикл for никогда не вводится. потому что 0 < 0 - false.

Вы можете исправить версии 1 обертывания push вызова внутри, если заявление, как это: (толчок будет, когда steamrollArray дозвонились с аргументом arr[0])

if(arr.length) // if length is not 0 
    accum = accum.concat(steamrollArray(arr[0])); 

Вспомогательных 2:NodeJs является отличным временем выполнения javascript. Он поставляется с интерфейсом командной строки. Попробуй!

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