Перемещение нулей в конец в массиве

Напишите алгоритм, который принимает массив и перемещает все нули в конец, сохраняя порядок других элементов. moveZeros([false,1,0,1,2,0,1,3,"a"]) // returns[false,1,1,2,1,3,"a",0,0] Я написал такое решение, но оно проходит не все проверки и я не могу понять что не так.

function  moveZeros(arr){
    let count = 0;
    for(let i = 0; i < arr.length; i++){
    if( arr[i] == 0){
        arr.splice(i,1);
        count += 1;
    }
    }
    for( let i = 0; i < count; i++){
        arr.push(0);
    }
 return arr;
 }

Ответы (7 шт):

Автор решения: Igor

Ваш код работает неправильно, когда нули идут подряд.

if (arr[i] == 0) {
    arr.splice(i, 1);
    count++;
    i--; // !!!
}
→ Ссылка
Автор решения: Stranger in the Q

Может так ?

let moveZeros = arr => arr.map((el, i) => [el, el === 0 ? Number.POSITIVE_INFINITY : i])
                          .sort((a, b) => a[1] - b[1])
                          .map(el => el[0]);

console.log(moveZeros([1,false,1,0,1,2,0,1,3,"a"]))

→ Ссылка
Автор решения: Yaant

Альтернативный подход:

function moveZeros (arr) {
  let res = arr.filter(el => el !== 0);
  return res.concat(new Array(arr.length - res.length).fill(0))
}

console.log (moveZeros([0, 0, 1, 2, true, false, 0, undefined, null, {}, 0, 3]))

→ Ссылка
Автор решения: Grundy

В приведенном решении стандартная проблема со splice, когда при удалении увеличивается счетчик и из-за этого пропускается следующий элемент.

Эту проблему можно обойти, если запустить цикл не с 0, а с arr.length.


Альтернативным решением может стать обмен нулевых значений, на ненулевые при проходе.

function moveZeros(arr) {
  for (var i = 0, j = 0; i < arr.length; i++) { // бежим по массиву
    if (arr[i] !== 0) { // если i-ый элемент не 0
      [arr[j], arr[i]] = [arr[i], arr[j]]; // меняем местами i-ый и j-ый элементы
      j++; // увеличиваем счетчик j
    }
  }
  return arr;
}

console.log(moveZeros([false, 1, 0, 1, 2, 0, 1, 3, "a"]))
console.log(moveZeros([false, 0, 0, 0, 2, 0, 1, 3, "a", 0, 1, 1, 0, 0, 0]))
console.log(moveZeros([false, 1, 2, 1, 3, "a"]))

→ Ссылка
Автор решения: Olena
function moveZeros(arr) {
  let zeroArr = [];

  for (let i = 0; i <= arr.length; i += 1) {
    if (arr[i] === 0) {
      zeroArr.push(arr[i]);
    }
  }

  const noZeroArr = arr.filter(el => el !== 0);

  return [...noZeroArr, ...zeroArr];
}

moveZeros([false, 1, 0, 1, 2, 0, 1, 3, 'a', 2, 0, 5, 6]);
function moveZeros(arr) {
    const zeroArr = arr.filter(el => el === 0);
    const noZeroArr = arr.filter(el => el !== 0); 
    return [...noZeroArr, ...zeroArr]; 
} 
moveZeros([false, 1, 0, 1, 2, 0, 1, 3, 'a', 2, 0, 5, 6])
→ Ссылка
Автор решения: ksa

Мои 5коп...

console.log(moveZeros([false, 1, 0, 1, 2, 0, 1, 3, 'a', 2, 0, 5, 6]))
//
function moveZeros(a) {
  return a.sort((a, b) => {
    if (a === b) return 0
    if (b === 0) return -1
    return 1
  })
}

→ Ссылка
Автор решения: Eugene X
let input = [false,1,0,1,2,0,1,3,"a"]
console.log(input)
input.sort((a,b) => {
    if (a === 0) return 1;
    if (b === 0) return -1;
    return 0;
})
console.log(input);
→ Ссылка