Is there any way to sort the items as shows in the examples?
In the examples i show how the objects must be sorted based the type.
// don't sort anything if typeA is 'p' always the 'p' must be on top
[{typeA: 'p', typeB: '', typeC: 8, typeD: 'N'}]
[{typeA: 'p', typeB: '', typeC: 0, typeD: 'C'}]
[{typeA: 'p', typeB: '', typeC: 10, typeD: 'O'}]
[{typeA: 'p', typeB: '', typeC: 3, typeD: 'H'}]
[{typeA: 'p', typeB: '', typeC: 0, typeD: 'H'}]
[{typeA: 'p', typeB: '', typeC: 5, typeD: 'N'}]
[{typeA: 'p', typeB: '', typeC: 1, typeD: 'A'}]
// result N,C,O,H,H,N,A
// if typeB exist 't' sort typeB by typeC numerical order
[{typeA: '', typeB: 't', typeC: 10, typeD: 'O'}]
[{typeA: '', typeB: 't', typeC: 8, typeD: 'N'}]
[{typeA: '', typeB: 't', typeC: 5, typeD: 'N'}]
[{typeA: '', typeB: 't', typeC: 3, typeD: 'H'}]
[{typeA: '', typeB: 't', typeC: 1, typeD: 'A'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'C'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'M'}]
//result O,N,N,H,A,C,M
// if typeB exist 't' and typeC = 0 sort typeB by typeD
[{typeA: '', typeB: 't', typeC: 0, typeD: 'A'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'C'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'H'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'N'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'N'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'M'}]
[{typeA: '', typeB: 't', typeC: 0, typeD: 'O'}]
//result A,C,H,N,N,M,O
Notice that in the array of objects maybe exists and typaA ‘p’ and typeB ‘t’ ex:
[{typeA: 'p', typeB: '', typeC: 8, typeD: 'N'}]
[{typeA: 'p', typeB: '', typeC: 0, typeD: 'C'}]
[{typeA: '', typeB: 't', typeC: 10, typeD: 'O'}]
[{typeA: 'p', typeB: '', typeC: 3, typeD: 'H'}]
[{typeA: 'p', typeB: '', typeC: 0, typeD: 'H'}]
[{typeA: '', typeB: 't', typeC: 5, typeD: 'N'}]
[{typeA: 'p', typeB: '', typeC: 1, typeD: 'A'}]
//result N,C,H,H,A,O,N
for (let i = 0; i < items.length; i++) {
var list = document.getElementById('holder');
[...list.children]
.sort // sort it here as we want and put it in the list
.forEach(node => list.appendChild(node));
}
Thanks in advance.
2
Playing around with this as a thought experiment, I revisited an article I’d written about something similar – how we can sort objects by multiple properties. So taking your code and defining each sort-rule, we can do something like this:
let things = [
{typeA: 'p', typeB: '', typeC: 8, typeD: 'N'},
{typeA: 'p', typeB: '', typeC: 0, typeD: 'C'},
{typeA: 'p', typeB: '', typeC: 10, typeD: 'O'},
{typeA: 'p', typeB: '', typeC: 3, typeD: 'H'},
{typeA: 'p', typeB: '', typeC: 0, typeD: 'H'},
{typeA: 'p', typeB: '', typeC: 5, typeD: 'N'},
{typeA: 'p', typeB: '', typeC: 1, typeD: 'A'},
{typeA: '', typeB: 't', typeC: 10, typeD: 'O'},
{typeA: '', typeB: 't', typeC: 8, typeD: 'N'},
{typeA: '', typeB: 't', typeC: 5, typeD: 'N'},
{typeA: '', typeB: 't', typeC: 3, typeD: 'H'},
{typeA: '', typeB: 't', typeC: 1, typeD: 'A'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'C'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'M'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'A'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'C'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'H'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'N'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'N'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'M'},
{typeA: '', typeB: 't', typeC: 0, typeD: 'O'}
]
const typeARule = (a,b)=>
a.typeA===b.typeA ?
0 :
a.typeA==='p' ?
-1 :
1;
const typeBAndCRule = (a, b)=>
a.typeB==='t' && b.typeB==='t'
&& (a.typeC>0 || b.typeC>0) ?
b.typeC - a.typeC :
0;
const typeBAndDRule = (a, b)=>
a.typeB==='t' && b.typeB==='t' ?
a.typeD.localeCompare(b.typeD) :
0;
const byAll = (a,b)=>
typeARule(a,b) || typeBAndCRule(a,b) || typeBAndDRule(a,b);
console.log( things.sort(byAll));
So we have your array of objects, each with four properties. And we define the particular rules as sorting functions in themselves. As an example, we can use:
const typeBAndCRule = (a, b)=>
a.typeB==='t' && b.typeB==='t'
&& (a.typeC>0 || b.typeC>0) ?
b.typeC - a.typeC :
0;
That says “if both typeB properties are "t"
, and either typeC property is non-zero, sort them by that typeC property (returning a -1 or 1). In every other case, return a 0.”
The neat thing about that “zero-case” in the sort function? If we logically structure them, then the zero is the only falsy case, letting us chain multiple sort-functions together:
const byAll = (a,b)=>
typeARule(a,b) || typeBAndCRule(a,b) || typeBAndDRule(a,b);
The first one to evaluate to a non-zero (and thus non-falsy) value will stop the evaluation and return that non-zero value, telling our sort to either use the 1
or -1
case.
there are issues. I have not done the typeARule
as robustly as I might – you want to weight all the "p"
cases to the top, and all empty cases after, but we haven’t really specified if there are other typeA
options or how to handle them. Additionally, in your second set of “sort”, you list a few cases where typeC
is zero – so in a larger set, they’ll simply be seen as “we’re placing all typeC zero values at the end, and then sorting all typeC zero-values by typeD.”
The idea here is sound – if you can explicitly define the sort rules, you can chain them in this way. But I would suggest you really want to clearly define those sort rules, you haven’t at this point.
1