Sort an array of object by a property (with custom order, not alphabetically)

允我心安 提交于 2020-01-08 13:24:09

问题


I would like to get your help about this little problem.

I have like to order this array depending on the code value but not in alphabetical order. (I specified this in bold but got eventually flagged anyway, people don't even care about reading the question)

For example I would like to have all the green objects, then all the blue ones and then all the red ones. What is the best way to do that?

[
    { code: "RED", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0}
]

Is it possible to do that with the sort function? What would the condition be in that case?


回答1:


You could take an object for the wanted order.

var array = [{ code: "RED", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }],
    order = { GREEN: 1, BLUE: 2, RED: 3 };
    
array.sort(function (a, b) {
    return order[a.code] - order[b.code];
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For unknow colors/values, you could use a default value with

  • 0, for sorting to top or
  • Infinity for sorting to the end,
  • or any other value for sorting inbetween the other groups.

At last you could sort the special treated items with an other sorting part, chained with logical OR ||.

var array = [{ code: "YELLOW", value: 0 }, { code: "BLACK", value: 0 }, { code: "RED", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }],
    order = { GREEN: 1, BLUE: 2, RED: 3, default: Infinity };
    
array.sort(function (a, b) {
    return (order[a.code] || order.default) - (order[b.code] || order.default) || a.code.localeCompare(b.code);
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }



回答2:


Set the custom priority first

var codePriority = [ "GREEN", "BLUE", "RED" ];

Now use the same in sorting as

arr.sort( function(a,b){ 
   if ( a.code == b.code ) return a.value - b.value;
   return codePriority.indexOf( a.code ) - codePriority.indexOf( b.code ) ; notice this line
})

Demo

var arr = [
    { code: "RED", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0}
];
var codePriority = [ "GREEN", "BLUE", "RED" ];
arr.sort( function(a,b){ 
   if ( a.code == b.code ) return a.value - b.value;
   return codePriority.indexOf( a.code ) - codePriority.indexOf( b.code )
});
console.log( arr );



回答3:


You could implement a schema array and sort according to element's index inside that schema array.

const a = ['GREEN', 'BLUE', 'RED'];

const o = [{code:"RED",value:0},{code:"BLUE",value:0},{code:"RED",value:0},{code:"GREEN",value:0},{code:"BLUE",value:0},{code:"RED",value:0},{code:"GREEN",value:0},{code:"BLUE",value:0}];

const r = o.slice().sort(({ code: q }, { code: w }) => a.indexOf(q) - a.indexOf(w));

console.log(r);


来源:https://stackoverflow.com/questions/47158756/sort-an-array-of-object-by-a-property-with-custom-order-not-alphabetically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!