1

I have an array something like this:

[
    {id: 5, attr: 99},
    {id: 7, attr: null},
    {id: 2, attr: 8},
    {id: 9, attr: 3},
    {id: 4, attr: null}
]

What would be the most efficient to put all objects with attr === null at the beginning of the array, without changing order of other elements in the array? (e.g. I need ids to go in this order: 7, 4, 5, 2, 9 (the order of 7 and 4 don't matter, but the order of 5, 2, 9 must never change.)

Simple fiddle to test your code: http://jsfiddle.net/8GEPC/

Dalius
  • 726
  • 1
  • 8
  • 19
  • Please comment if I didn't explain something clearly enough. – Dalius Mar 31 '14 at 15:32
  • Do you really need to have the most efficient way? It probably doesn't matter... Look into [these answers](http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects) – Laoujin Mar 31 '14 at 15:40
  • Efficiency doesn't really matter, I just like making everything as fast as possible :) – Dalius Mar 31 '14 at 15:44

4 Answers4

3

Could used built in filter methods that require two loops or one while loop to find the elements and remove them.

var x = [
    {id: 5, attr: 99},
    {id: 7, attr: null},
    {id: 2, attr: 8},
    {id: 9, attr: 3},
    {id: 4, attr: null}
];

var temp = [];
for(var i = x.length-1;i>=0;i--){
    if (x[i].attr===null) {               //if we have a null
        temp.unshift(x.splice(i,1)[0]);   //remove the element from org and add to temp
    }
}
x = temp.concat(x);  //add the original to the temp to maintain the order
epascarello
  • 204,599
  • 20
  • 195
  • 236
2
var arr = [
    {id: 5, attr: 99},
    {id: 7, attr: null},
    {id: 2, attr: 8},
    {id: 9, attr: 3},
    {id: 4, attr: null}
]

var nulls = arr.filter(function(a){return a.attr === null});
var notnulls = arr.filter(function(a){return a.attr !== null});

nulls.concat(notnulls);

// outputs [{"id":7,"attr":null},{"id":4,"attr":null},{"id":5,"attr":99},{"id":2,"attr":8},{"id":9,"attr":3}]

And here's a solution using reduce:

var sorted = arr.reduce(function(output, element) {
  if (element.attr === null)
    output.unshift(element);
  else
    output.push(element);
  return output
}, []);
console.log(sorted);
000
  • 26,951
  • 10
  • 71
  • 101
1

Grab the objects where attr === null.

var withNull = arr.filter(function (el) { return el.attr === null });

Grab the objects where attr !== null.

var withVal = arr.filter(function (el) { return el.attr !== null });

Add the 'null array' to the front of the 'values array'.

withVal.unshift.apply(withVal, withNull);

Fiddle

Andy
  • 61,948
  • 13
  • 68
  • 95
0
function customSort(myArray) {
  var result = [];
  myArray.map(function(el, idx, arr) {
    return myArray[idx].attr === null ? result.unshift(myArray[idx]) : result.push(myArray[idx]);
  });
  return result;
}
console.log(customSort([
    {id: 5, attr: 99},
    {id: 7, attr: null},
    {id: 2, attr: 8},
    {id: 9, attr: 3},
    {id: 4, attr: null}
]));
Adnan Topal
  • 236
  • 2
  • 5