Reputation: 8638
I'm wanting to sort an array of arrays based on a array and then by length of items in the array.
Take the following master sort array:
const key = [
"meraki",
"gsuite",
"active directory",
"sophos",
"manageengine"
]
I want to take a array that resembles:
const raw = [
["manageengine"],
["sophos"],
["active directory"],
["gsuite"],
["meraki"],
["sophos", "manageengine"],
["active directory", "sophos"],
["active directory", "manageengine"],
["gsuite", "active directory"],
["gsuite", "sophos"],
["gsuite", "manageengine"],
["meraki", "gsuite"],
["meraki", "active directory"],
["meraki", "sophos"],
["meraki", "manageengine"],
["active directory", "sophos", "manageengine"],
["gsuite", "active directory", "sophos"],
["gsuite", "active directory", "manageengine"],
["gsuite", "sophos", "manageengine"],
["meraki", "gsuite", "active directory"],
["meraki", "gsuite", "sophos"],
["meraki", "active directory", "sophos"],
["meraki", "gsuite", "manageengine"],
["meraki", "active directory", "manageengine"],
["meraki", "sophos", "manageengine"],
["gsuite", "active directory", "sophos", "manageengine"],
["meraki", "gsuite", "active directory", "sophos"],
["meraki", "gsuite", "active directory", "manageengine"],
["meraki", "gsuite", "sophos", "manageengine"],
["meraki", "active directory", "sophos", "manageengine"],
["meraki", "gsuite", "active directory", "sophos", "manageengine"]
];
In the above example, I want the raw
array to be sorted by accordingly to each item in the key
array. My first attempt was to do something like:
const result = [];
for (const name of result) {
const sorted = keys.filter((s) => s[0] === name);
result.push(...sorted);
}
result.sort((a, b) => a.length - b.length);
However that only takes into account the first item in the array, not the sort of the rest of the items.
Upvotes: 0
Views: 120
Reputation: 21110
To sort you have to first check the length. If both are equal we have to check the index positions of the first element of a
/b
within key
. If those are the same move on to the next element in both arrays.
This answer makes use of the fact that 0
is a falsey value. Examples are: 0 || -1 //=> -1
and 1 || -1 //=> 1
const key = ["meraki", "active directory", "sophos"];
const raw = [
["meraki"],
["active directory"],
["sophos", "active directory"],
["active directory", "sophos"],
["sophos"],
["meraki", "active directory", "sophos"],
];
raw.sort((a, b) => (
a.length - b.length || a.reduce((diff, _, i) => (
diff || key.indexOf(a[i]) - key.indexOf(b[i])
), 0)
));
console.log(raw);
console.table(raw); // check browser console
Upvotes: 1
Reputation: 15098
Consider below approach
const key = [
"meraki",
"active directory",
"sophos"
]
const raw = [
["sophos"],
["meraki"],
["active directory"],
["sophos", "active directory"],
["active directory", "sophos"],
["meraki", "active directory", "sophos"]
]
const compareThis = (a, b) => {
if (a.length !== b.length) {
return a.length - b.length
}
let itemFound = 0;
for (let keyIndex in key) {
for (let aIndex in a ) {
if(a[aIndex] === key[keyIndex]) {
itemFound = -1;
break;
}
if(b[aIndex] === key[keyIndex]) {
itemFound = 1;
break;
}
}
if(itemFound !== 0) { break }
}
return itemFound;
}
const sortedData = raw.sort(compareThis)
console.log(sortedData)
Upvotes: 1