Reputation: 2933
I have an array :
var array = [
{ID : 1,
Name : one,
data : {more info here}
},
{ID : 2,
Name : two
},
{ID : 3,
Name : three,
data : {more info here}
},
{ID : 4,
Name : four
},
{ID : 5,
Name : five,
data : {more info here}
},]
Need to sort these array, where data is present will be top, then other. Final sort result will be -
[{ID:1,name: one,data: {}},
{ID:3,name: three,data: {}},
{ID:5,name: five,data: {}},
{ID:2,name: two},
{ID:4,name: four}]
Upvotes: 0
Views: 56
Reputation: 33366
It is not clear from the question if the only thing that matters in the desired sort is the presence or absence of the data
property. The desired "final sort result" shows the data sorted first by the presence or absence of data
, but then in ascending order of ID
within those groups. It is possible that sorting by ID
is merely an artifact of the starting array order and is not a required part of the question. On the other hand, it may be that sorting by both data
and then ID
are both required.
The other solutions either do not sort at all based on the ID
(Nina Scholz's answer), or sort by both data
and ID
, but do so erroneously depending on the input array (Rajesh's answer). Both rely on the order of the input array to provide the desired result array.
The following code will sort the array based first on the presence or absence of data
and then by ID
within those two sub groups.
Sorting the originally provided input array:
var array = [{ ID: 1, Name: 'one', data: {} }, { ID: 2, Name: 'two' }, { ID: 3, Name: 'three', data: {} }, { ID: 4, Name: 'four' }, { ID: 5, Name: 'five', data: {} }];
array.sort(function(a, b) {
if(a.data && !b.data) {
// a has data, b does not have data, a is first
return -1;
}
if(!a.data && b.data) {
// a does not have data, b does have data, b is first
return 1;
}
// a and b either both have data, or both don't have data. Sort the smaller ID first.
return a.ID - b.ID;
});
console.log(array)
Below is the same sort starting with an input array slightly modified from the one used in Rajesh's updated answer. The array from that answer has been modified to change ID:4,
to ID:41,
. With that modified input array, Rajesh's sort will produce erroneous results. This code will sort it correctly by both data
and ID
.
var array=[{ID:1,Name:"one",data:{"more info here":"something"}},{ID:2,Name:"two"},{ID:30,Name:"Thirty",data:{"more info here":"something"}},{ID:41,Name:"four"},{ID:5,Name:"five",data:{"more info here":"something"}},{ID:40,Name:"fourty",data:{"more info here":"something"}},{ID:300,Name:"threeHundred",data:{"more info here":"something"}},{ID:20,Name:"twenty"},{ID:3e3,Name:"threeThousand",data:{"more info here":"something"}}];
array.sort(function(a, b) {
if(a.data && !b.data) {
// a has data, b does not have data, a is first
return -1;
}
if(!a.data && b.data) {
// a does not have data, b does have data, b is first
return 1;
}
// a and b either both have data, or both don't have data. Sort the smaller ID first.
return a.ID - b.ID;
});
console.log(array)
Upvotes: 0
Reputation: 386746
You could use the delta of the boolen values of the properties.
var array = [{ ID: 1, Name: 'one', data: {} }, { ID: 2, Name: 'two' }, { ID: 3, Name: 'three', data: {} }, { ID: 4, Name: 'four' }, { ID: 5, Name: 'five', data: {} }];
array.sort(function (a, b) {
return !a.data - !b.data;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another version with stress on the key could be the check for existence.
var array = [{ ID: 1, Name: 'one', data: {} }, { ID: 2, Name: 'two' }, { ID: 3, Name: 'three', data: {} }, { ID: 4, Name: 'four' }, { ID: 5, Name: 'five', data: {} }];
array.sort(function (a, b) {
return ('data' in b) - ('data' in a);
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3