1

I need to sort a list of array by a particular word. Any help would be appreciated. Thank you.

 List=[microphone,phone,telephone,mobilephone]
    
 word="pho"

Answer should be,

answer=[phone,telephone,microphone,mobilephone]

Katara
  • 66
  • 1
  • 10

2 Answers2

5

You can use the indexOf() to get an index number and pass that to the sort method.

const list = ["microphone", "phone", "telephone", "mobilephone"];

const sortBySubstring = (words, match) => {
  return words.sort((a, b) => {
    return a.indexOf(match) - b.indexOf(match);
  });
}

const result = sortBySubstring(list, "pho");

console.log(result);

EDIT:

If there is a word in your list that doesn't contain the substring it will be placed at the beginning of the array. There are some ways to change this behaviour.

First of all you could check if it exists with includes(), if it doesn't exist put it at the end the array

const list = ["microphone", "phone", "telephone", "mobilephone", "telemobile"];

const sortBySubstring = (words, match) => {
  return words.sort((a, b) => {
    if(!a.includes(match) || !b.includes(match)) return 1;
    
    return a.indexOf(match) - b.indexOf(match);
  });
}

const result = sortBySubstring(list, "pho");

console.log(result);

Another option is to filter() out words that don't contain your given substring

const list = ["microphone", "phone", "telephone", "mobilephone", "telemobile"];

const sortBySubstring = (words, match) => {
  const contains = words.filter((word) => word.includes(match));

  return contains.sort((a, b) => {
    return a.indexOf(match) - b.indexOf(match);
  });
}

const result = sortBySubstring(list, "pho");

console.log(result);
Reyno
  • 6,119
  • 18
  • 27
  • 1
    If the search is not found, it will move that word to the beginning of the array because `indexOf` returns `-1`. But OP hasn't mentioned that scenario. – adiga Dec 21 '20 at 11:00
  • That is a good starting point but it would require some refining; if you test it using substrings that are present only in some words (e.g. `sortBySubstring(list, "ile");` you'll see what I mean. – secan Dec 21 '20 at 11:02
  • Yes is didn't think about the fact that words without the substring would result in a different outcome, i've added some extra snippets to cover some of those flaws. – Reyno Dec 21 '20 at 11:59
2

Little bit longer than the answer by Reyno but it moves strings that don't exist in the array to the end.

// The following function was taken from here: https://stackoverflow.com/questions/16096872/how-to-sort-2-dimensional-array-by-column-value (answer by jahroy)
function compareSecondColumn(a, b) {
    if (a[1] === b[1]) {
        return 0;
    }
    else {
        return (a[1] < b[1]) ? -1 : 1;
    }
}


function sortByWord(list, word) {
    // put data into 2d array (x) with array item and indexOf search term
  var x = [];
  var doesntContainWord = [];
  for (var i = 0; i < list.length; i++) {
    if (list[i].indexOf(word) == -1) {
        // if the search word doesn't exist, push to array
      doesntContainWord.push(list[i]);
    } else {
        x[i] = [list[i], list[i].indexOf(word)];
    }
  }
  doesntContainWord.sort();
  // now sort var x by second col.
  x.sort(compareSecondColumn);
  // now dump values back into array and return them
  var toReturn = [];
  for (var i = 0; i < x.length; i++)     {
    toReturn[i] = x[i][0];
  }
  return toReturn.concat(doesntContainWord);
}

var data = ["microphone", "phone", "telephone", "mobilephone", "cat", "animal"];

console.log(sortByWord(data, "pho"))
JackChilds
  • 41
  • 1
  • 2
  • You can do that by sorting based on the existence of the `match` before going for the index comapre: `List.sort((a,b) => b.includes(match) - a.includes(match) || a.indexOf(match) - b.indexOf(match))` – adiga Dec 21 '20 at 11:44
  • Thank you Jack Childs for the support. – Katara Dec 21 '20 at 14:50