2016-07-21 9 views
0

Я написал программу перетасовки ниже и пропустил ее через "Will It Shuffle?". Результаты показывают, что они работают в консоли; это перетасовка массива. Но сайт показывает мне всю красную коробку, заставляя меня думать, что с моим кодом что-то не так, но я этого не вижу.Что не так с моей программой перетасовки?

function shuffle (array) { 
    var arr = [], 
     length = array.length, 
     el; 

    while (length > 0) { 
     var randomEl = Math.floor(Math.random() * (length - 0) - 0); 
     if (length > 1) { 
     el = array.splice(randomEl,1); 
     } else { 
     el = array.splice(0,1); 
     } 
     arr.push(el[0]); 
     length -= 1; 
    } 

    return arr; 
} 
+1

Вы проверили его в консоли? вы запустили их? Вы возвращаетесь, они этого не делают. Они изменяют массив, вы не – epascarello

+0

Из теста на массив от 1 до 10 он выглядит достаточно случайным, и я думаю, что проблема заключается в сайте Will It Shuffle. – HyperNeutrino

+0

@epascarello, Да, много раз. Кто-то сказал, что мой последний код сортировки не очень хорош и отправил мне этот сайт. Я написал это, протестировал его на этом веб-сайте, и ячейки полностью красные, хотя консоль показывает мне, что он перетасовывает массив. Извините, новичок в JS. – BeerBeard

ответ

1

Эта страница игнорирует возвращаемое значение функции, потому что она ожидает in-place рода.

Если добавить это в конце кода, он работает, как ожидалось:

array.push(...arr); 

Вы также можете сделать это на месте непосредственно:

function shuffle (array) { 
    var length = array.length; 
    while (length) { 
    var randomEl = Math.floor(Math.random() * length); 
    var el = array.splice(randomEl, 1); 
    array.push(el[0]); 
    --length; 
    } 
} 
+0

Спасибо, @Oriol. Я все еще изучаю JS, поэтому я не знаком с нажатием «... arr». Не могли бы вы объяснить, почему это работает с эллипсами? – BeerBeard

+1

@BeerBeard Это [оператор спреда] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). Например, если у вас есть 'arr = [1,2,3]', то 'array.push (... arr)' ведет себя как 'array.push (1,2,3)'. То есть, он выталкивает все элементы 'arr' в' array'. – Oriol

+0

Я нашел другие ответы полезными, но я очень ценю ваш ответ, особенно источники, которые вы предоставили оператору распространения, на месте, и другой вариант моего кода, выполняемый на месте. Хорошее обучение и благодарность. – BeerBeard

1

Они изменяют массив, вы не изменяйте массив.

Вам нужно изменить исходный массив, а не возвращать новый массив.

function shuffle (array) { 
    var arr = [], 
     length = array.length, 
     el; 

    while (length > 0) { 
     var randomEl = Math.floor(Math.random() * (length - 0) - 0); 
     if (length > 1) { 
     el = array.splice(randomEl,1); 
     } else { 
     el = array.splice(0,1); 
     } 
     arr.push(el[0]); 
     length -= 1; 
    } 

    //replace array with the new items 
    //it is like using concat, but does not produce a new array, 
    //just appends it to the original which has zero items in it. 
    Array.prototype.push.apply(array, arr); 



} 
+0

Я знаю, что вы имеете в виду, но этот ответ не очень ясен. [КТО нет нисходящего от меня :)) Пожалуйста, уточните. – HyperNeutrino

1

Что вы делаете, это создать новый массив с элементами оригинального перетасованного вокруг.

Однако, если вы вернетесь и посмотрите на массив, в который вы вошли, вы заметите, что его не перетасовали, а опорожнили. Видимо, это не то, что «будет ли оно перетасовывать?» просит вас сделать.

splice() и push() оба всегда мутируют массив, на который вы вызываете эти методы.

Чтобы ответить на ваш вопрос о .push (... arr), elipses в javascript - это функция, которая появилась с последней версией EcmaScript 2015. Это «оператор распространения».

Когда вы вызываете функцию с массивом «spread», это как вызов функции с содержимым массива в виде отдельных аргументов. Например,

array.push(...[1,2,3]) 

такой же, как вызов

array.push(1,2,3) 

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

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

  • Нет связанных вопросов^_^