Search code examples
javascriptarrayssortingjavascript-objects

Sort array of objects by containing string


I am trying to sort an array of objects by substring/string

var substring = 'nord';
var arrayOfObjs = [0: {label: "Nordals", value: "s29"}
1: {label: "Skåstrup Strand", value: "s12"}
2: {label: "Blokhus", value: "s61"}
3: {label: "Fanø", value: "s27"}
4: {label: "Rømø", value: "s26"}
5: {label: "Vorupør", value: "s66"}
6: {label: "Grønhøj", value: "s41"}
7: {label: "Nr. Lyngby ved Løkken", value: "s14"}
8: {label: "Nordjylland", value: "6"}
9: {label: "Nordsjælland", value: "7"}
10: {label: "Vestjylland", value: "10"}
11: {label: "Tyskland", value: "13"}];

I have this function to sort:

function compare(a, b) {
  // Use toUpperCase() to ignore character casing
  const areaA = a.label.toUpperCase();
  const areaB = b.label.toUpperCase();

  let comparison = 0;
  if (areaA > areaB) {
    comparison = 1;
  } else if (areaA < areaB) {
    comparison = -1;
  }
  return comparison;
}

Before sorting:

0: {label: "Nordals", value: "s29"}
1: {label: "Skåstrup Strand", value: "s12"}
2: {label: "Blokhus", value: "s61"}
3: {label: "Fanø", value: "s27"}
4: {label: "Rømø", value: "s26"}
5: {label: "Vorupør", value: "s66"}
6: {label: "Grønhøj", value: "s41"}
7: {label: "Nr. Lyngby ved Løkken", value: "s14"}
8: {label: "Nordjylland", value: "6"}
9: {label: "Nordsjælland", value: "7"}
10: {label: "Vestjylland", value: "10"}
11: {label: "Tyskland", value: "13"}

After sorting:

0: {label: "Blokhus", value: "s61"}
1: {label: "Fanø", value: "s27"}
2: {label: "Grønhøj", value: "s41"}
3: {label: "Nordals", value: "s29"}
4: {label: "Nordjylland", value: "6"}
5: {label: "Nordsjælland", value: "7"}
6: {label: "Nr. Lyngby ved Løkken", value: "s14"}
7: {label: "Rømø", value: "s26"}
8: {label: "Skåstrup Strand", value: "s12"}
9: {label: "Tyskland", value: "13"}
10: {label: "Vestjylland", value: "10"}
11: {label: "Vorupør", value: "s66"}

The array of objects is being sorted by the alphabet, but I need to sort the arrayOfObjects by the substring, so basically every arrayOfObjs[x].label that is closest to the substring variable has to come first in the sorted results?

How would I add this functionality?

It should look something like this because the 3 first contains the 'nord' string:

0: {label: "Nordals", value: "s29"}
1: {label: "Nordjylland", value: "6"}
2: {label: "Nordsjælland", value: "7"}
3: {label: "Blokhus", value: "s61"}
4: {label: "Fanø", value: "s27"}
5: {label: "Grønhøj", value: "s41"}
6: {label: "Nr. Lyngby ved Løkken", value: "s14"}
7: {label: "Rømø", value: "s26"}
8: {label: "Skåstrup Strand", value: "s12"}
9: {label: "Tyskland", value: "13"}
10: {label: "Vestjylland", value: "10"}
11: {label: "Vorupør", value: "s66"}

I have tried browsing through stack overflow, but I was unable to find anything, if this is a duplicate please show me the path.


Solution

  • You could sort by substring and then by alphabet.

    var array = [{ label: "Nordals", value: "s29" }, { label: "Skåstrup Strand", value: "s12" }, { label: "Blokhus", value: "s61" }, { label: "Fanø", value: "s27" }, { label: "Rømø", value: "s26" }, { label: "Vorupør", value: "s66" }, { label: "Grønhøj", value: "s41" }, { label: "Nr. Lyngby ved Løkken", value: "s14" }, { label: "Nordjylland", value: "6" }, { label: "Nordsjælland", value: "7" }, { label: "Vestjylland", value: "10" }, { label: "Tyskland", value: "13" }],
        string = 'nord';
    
    array.sort((a, b) =>
        b.label.toLowerCase().includes(string) - a.label.toLowerCase().includes(string) ||
        a.label.localeCompare(b.label)
    );
    
    console.log(array);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    IE version with classic function and String#indexOf.

    array.sort(function (a, b) {
        return (a.label.toLowerCase().indexOf(string) === -1) - (b.label.toLowerCase().indexOf(string) === -1)
            || a.label.localeCompare(b.label);
    });