I have an array of objects. Out of each of these objects onle few of them have a property and I want to sort the array putting those objects at top which have that property.
Ex -
arr= [{key1: "obj1val1", key2 :"obj1val2"},
{key2 :"obj2val2"},
{key1: "obj3val3", key2 :"obj3val3"},
{key2 :"obj4val1"},
{key1: "obj5val1", key2 :"obj5val2"}
]
Sorted by key1
Expected Result - [{key1: "obj1val1", key2 :"obj1val2"},
{key1: "obj3val3", key2 :"obj3val3"},
{key1: "obj5val1", key2 :"obj5val2"},
{key2 :"obj2val2"},
{key2 :"obj4val1"}]
I have tried below approach-
sort : function(arr) {
var copyArr = arr.slice();
var newArr = [];
for(var i=0; i<arr.length; i++){
if(arr[i].key1){
newArr.push(arr[i]);
copyArr.splice(i, 1);
}
}
Array.prototype.push.apply(newArr, copyArr);
return newArr;
}
Not exactly but I see discrepancy from the above approach. For a array bigger length, some of the objects which have key1 are not moved to top.
Can this be done by internal sort
method of javascript? If yes, how will the custom function compare ?
Can only support ES5 methods.
I have an array of objects. Out of each of these objects onle few of them have a property and I want to sort the array putting those objects at top which have that property.
Ex -
arr= [{key1: "obj1val1", key2 :"obj1val2"},
{key2 :"obj2val2"},
{key1: "obj3val3", key2 :"obj3val3"},
{key2 :"obj4val1"},
{key1: "obj5val1", key2 :"obj5val2"}
]
Sorted by key1
Expected Result - [{key1: "obj1val1", key2 :"obj1val2"},
{key1: "obj3val3", key2 :"obj3val3"},
{key1: "obj5val1", key2 :"obj5val2"},
{key2 :"obj2val2"},
{key2 :"obj4val1"}]
I have tried below approach-
sort : function(arr) {
var copyArr = arr.slice();
var newArr = [];
for(var i=0; i<arr.length; i++){
if(arr[i].key1){
newArr.push(arr[i]);
copyArr.splice(i, 1);
}
}
Array.prototype.push.apply(newArr, copyArr);
return newArr;
}
Not exactly but I see discrepancy from the above approach. For a array bigger length, some of the objects which have key1 are not moved to top.
Can this be done by internal sort
method of javascript? If yes, how will the custom function compare ?
Can only support ES5 methods.
Share Improve this question edited Sep 22, 2018 at 21:46 David Thomas 253k53 gold badges381 silver badges418 bronze badges asked Sep 22, 2018 at 21:35 RahulBRahulB 2,1101 gold badge20 silver badges27 bronze badges 5 |4 Answers
Reset to default 15Can this be done by internal sort method of javascript
Yes: Simply prefer the entry that has the property:
arr.sort(function(left, right) {
return left.hasOwnProperty("key1") ? -1 : right.hasOwnProperty("key1") ? 1 : 0
});
Live Example:
var arr = [
{key1: "obj1val1", key2 :"obj1val2"},
{key2 :"obj2val2"},
{key1: "obj3val3", key2 :"obj3val3"},
{key2 :"obj4val1"},
{key1: "obj5val1", key2 :"obj5val2"}
];
arr.sort(function(left, right) {
return left.hasOwnProperty("key1") ? -1 : right.hasOwnProperty("key1") ? 1 : 0
});
console.log(arr);
If you also want to sort by that property's value:
arr.sort(function(left, right) {
var leftHas = left.hasOwnProperty("key1");
var rightHas = right.hasOwnProperty("key1");
if (leftHas && rightHas) {
return left.key1.localeCompare(right.key1);
}
return leftHas ? -1 : rightHas ? 1 : 0;
});
Live Example:
var arr = [
{key1: "obj1val1", key2 :"obj1val2"},
{key2 :"obj2val2"},
{key1: "obj3val3", key2 :"obj3val3"},
{key2 :"obj4val1"},
{key1: "obj5val1", key2 :"obj5val2"}
];
arr.sort(function(left, right) {
var leftHas = left.hasOwnProperty("key1");
var rightHas = right.hasOwnProperty("key1");
if (leftHas && rightHas) {
return left.key1.localeCompare(right.key1);
}
return leftHas ? -1 : rightHas ? 1 : 0;
});
console.log(arr);
Here is a working snippet that gives your requested result and is easily extended. It uses the native array sort
.
arr = [{
key1: "obj1val1",
key2: "obj1val2"
},
{
key2: "obj2val2"
},
{
key1: "obj3val3",
key2: "obj3val3"
},
{
key2: "obj4val1"
},
{
key1: "obj5val1",
key2: "obj5val2"
}
]
const sorted = arr.sort((a, b) => {
const k1 = a.key1 === undefined ? 0 : 1
const k2 = b.key1 === undefined ? 0 : 2
return k2- k1
})
console.log(sorted)
A kind of janky way you can do it is:
arr.filter(obj => obj.hasOwnProperty('key1')).concat(arr.filter(obj => !obj.hasOwnProperty('key1')));
https://github.com/arraybrain/arraybrain
for complex array stuff, you can use it
splice
while you are iterating. – Bergi Commented Sep 22, 2018 at 21:39sort
. – Bergi Commented Sep 22, 2018 at 21:40splice
out one element. – Bergi Commented Sep 22, 2018 at 21:43var withProp = [], withoutProp = []; … if ("key1" in arr[i]) withProp.push(arr[i]); else withoutProp.push(arr[i]); …
. Don't copy anything beforehand or try to splice from it during a loop. – Bergi Commented Sep 22, 2018 at 21:44