0

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.

4

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Another option would be a.reduce((diff, a, i) => diff || key.indexOf(a) - key.indexOf(b[i]), 0) instead of upto(a.length).reduce(...) but I despise the asymmetry in that solution.
1

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)

3 Comments

Side note: you are missing the 'var' in the 'for' loops
I think its inverted now.
Could you share a wider array for debugging?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.