0

I have an array of words like the one below:

arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"]

I would like to sort it, but ignoring the first word. For example, the output would be:

arr = ["id-3 abc home", "id1 abc test", "id#2 XX car house"]

Thanks

7
  • 2
    What are the sorting rules here ? Please be more clear Commented Aug 7, 2020 at 15:27
  • sort lexicographically ignoring the first word. In the example, "id1", "id-3", and "id#2" should not be considerate in the sorting Commented Aug 7, 2020 at 15:30
  • So are you considering the unicode code point while sorting ? Still unsure about the rules Commented Aug 7, 2020 at 15:32
  • Why id1 abc test is before id-3 abc home? Commented Aug 7, 2020 at 15:45
  • I'm sorry, id-3 abc home should be before Commented Aug 7, 2020 at 18:51

3 Answers 3

1

You can use array.sort where you searchb the index of the space from the string and take for the comparison the original-string just from one position after the space.

Remark: For implementing the sort-function you have pay attention that there are 3 different return values for (a,b):

  • Return: < 0 => a<b
  • Return: = 0 => a=b
  • Return: < 0 => a>b

The result is now ok after I consider this (I had made here a mistake which is now corrected):
"id#2 XX car house", "id-3 abc home", "id1 abc test"

Note: XX stands before abc because uppercases are smaller than lowercases e.g. ASCII from "A" is 65 and from "a" is 97.

console.log('A'.charCodeAt(0));
console.log('a'.charCodeAt(0));

Here is the code-sample in extended version because it's not 100% clearified if for sorting the upper/lowercase-problematic is to be considered or not. So I added an extra parameter, so that now both variants are possible:

let arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"];

function specialSort(ignoreUpperCase) {
    arr.sort( (a,b) => {
        if (ignoreUpperCase) {
            a = a.toUpperCase();
            b = b.toUpperCase()
        }
        a = a.substr(a.indexOf(' ')+1);
        b= b.substr(b.indexOf(' ')+1);
        return (a<b) ? -1 : (a>b) ? 1 : 0;
   });
}

specialSort(true);
console.log('Ignore UpperCases:',arr);

specialSort(false);
console.log('With UpperCases:',arr);

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

7 Comments

Hi, it doesn't sort for the ones that have the same second word. In the example, id-3 abc home should come before id1 abc test
@myTest532 myTest532 You are right I made a mistake with the return-values from the sort-function. But you made a mistake for the result, it is: "id#2 XX car house", "id-3 abc home", "id1 abc test" because X<a. For explanation look at my answer above.
@ Peter Seliger The OP wanted to sorted it from beginnig of the second word till the end of string. There stands nothing that he wants to be sorted without uppper/lowercase consideration, so his result is wrong or he had to specify more.
@ Peter Seliger I edited 20 minutes ago, yes (this was before you sayed something). I didn't do anything wrong with this. Because the OP itself approved it, so it is ok. I can't edit anything here without approving from the OP for this I haven't enough reputation..
@ Peter Seliger I extended my sorting for both variants, so the OP can decide by himself which one he prefers. I see that you re-editted the question to the last version. That's ok (because the OP approved it) but I would prefer that than there is a hint in the question that uppper/lowercase doesn't matter. But I don't want to start a quarrel about this.
|
0

function getStringWithoutFirstWord(str) {
  return str.split(/\s+/).slice(1).join(' ');
}

function compareLoacallyWhilstIgnoringFirstWord(a, b) {
  a = getStringWithoutFirstWord(a); // yes, this is a ...
  b = getStringWithoutFirstWord(b); // ... highly repetitive task.
  return a.localeCompare(b);
}
function compareStronglyAscendingWhilstIgnoringFirstWord(a, b) {
  a = getStringWithoutFirstWord(a);  // yes, this is a ...
  b = getStringWithoutFirstWord(b); // ... highly repetitive task.
  return ((a < b && -1) || (a > b && 1) || 0);
}

const arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"];


console.log(
  arr.sort(compareLoacallyWhilstIgnoringFirstWord)
);
console.log(
  arr.sort(compareStronglyAscendingWhilstIgnoringFirstWord)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

... a working implementation of the already by Hassan Imam mentioned decorate-sort-undecorate approach ...

function getStringWithoutFirstWord(str) {
  return str.split(/\s+/).slice(1).join(' ');
}

function restoreStringFromDecoratedIgnoredFirstWordData(data) {
  return data.original;
}
function createDecoratedIgnoredFirstWordData(str) {
  return {
    original: str,
    sortable: getStringWithoutFirstWord(str)
  }
}

function compareSortablesLoacally(a, b) {
  return a.sortable.localeCompare(b.sortable);
}
function compareSortablesStronglyAscending(a, b) {
  a = a.sortable;
  b = b.sortable;
  return ((a < b && -1) || (a > b && 1) || 0);
}

const arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"];


console.log(arr
  .map(createDecoratedIgnoredFirstWordData)
  .sort(compareSortablesLoacally)
  .map(restoreStringFromDecoratedIgnoredFirstWordData)
);

console.log(arr
  .map(createDecoratedIgnoredFirstWordData)
  .sort(compareSortablesStronglyAscending)
  .map(restoreStringFromDecoratedIgnoredFirstWordData)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Comments

0

This can be done with regular Array.prototype.sort and a small regex that ignores first word:

const arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"]

const result = arr.sort((a,b) => {

  const [aStr, bStr] = [a,b].map(l => l.replace(/^\S+/g,''));

  return aStr.localeCompare(bStr)

})

console.log(result);

1 Comment

Thank you. Is it possible to do without regex?

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.