Dexygen
Dexygen

Reputation: 12561

How to move non-empty values to the front of a Javascript array

Given the array:

var arr = ['', 'foo', '', 'bar', '', 'baz', ''];

I would like to get back:

[ 'foo', 'bar', 'baz', '', '', '', '' ]

Upvotes: 0

Views: 198

Answers (3)

Slai
Slai

Reputation: 22876

Questionable performance, but:

var arr = ['', 'foo', '', 'bar', '', 'baz', ''];

arr.forEach((v, i) => v || (arr.splice(i, 1), arr.push(v)) );

console.log(arr)

Of course, in-place swap solution without resizing or creating extra arrays would be more efficient:

var arr = ['', 'foo', '', 'bar', '', 'baz', ''];

for (var i = 0, j = arr.length - 1, v; ; ++i, --j) {
  while (arr[i]) ++i
  while (!arr[j]) --j
  if (i >= j) break
  v = arr[i]
  arr[i] = arr[j]
  arr[j] = v
}

console.log(arr)

Or preserving order:

var arr = ['', 'foo', '', 'bar', '', 'baz', '']

for (var i = 0, j = 1, len = arr.length, v; ; ++i, ++j) {
  while (arr[i]) ++i
  while (!arr[j] && j < len) ++j
  if (j >= len) break
  v = arr[i]
  arr[i] = arr[j]
  arr[j] = v
}

console.log(arr)

Upvotes: 0

Sean Johnson
Sean Johnson

Reputation: 5607

I would go with a custom sort function, like this:

['', 'foo', '', 'bar', '', 'baz', ''].sort((a, b) => !a ? 1 : !b ? -1 : 0);
// returns: ["foo", "bar", "baz", "", "", "", ""]

Upvotes: 5

Dexygen
Dexygen

Reputation: 12561

One non-ES6 way to do it is:

var arr = ['', 'foo', '', 'bar', '', 'baz', ''];
arr = arr.filter(function(val){return val}).concat(arr.filter(function(val){return !val}));

Or, using ES6 to shorten things:

arr = arr.filter((val) => val).concat(arr.filter((val) => !val));

Upvotes: 0

Related Questions