Home > Back-end >  How to sort array by number elements and ignore string elements
How to sort array by number elements and ignore string elements

Time:01-25

How can I sort an array in ascending order by the elements which are numbers while putting the elements that are strings at the back of the array?

I have tried this but I don't think it's correct(all ql ids that are strings as "NOT_SET", I want to have them at the back of the array (in typescript):

 const qaInspectionLinesSorted = _.forEach(qaInspectionLinesGroupedByType, (item => {
        return item.sort((ql1, ql2) => {
          if (ql1.id.toString() !== "NOT_SET") {
            return 0; 
          }
          if (ql1.id.toValue() > ql2.id.toValue()) {
            return 1;
          } else if (ql1.id.toValue() < ql2.id.toValue()) {
            return -1;
          }
          return 0;

        });
      }));

An item has this structure if it helps:

 _id: UniqueEntityID { value: 9 },
 props: {
   qaInspectionTypeId: [QAInspectionTypeId],
   qaInspectionLineStatusId: [QAInspectionStatusId],
   qaInspectionLineNotes: 'HIIIIII',
   qaInspectionId: 1
 }

CodePudding user response:

Your comparator is returning 0 when ql1.id.toString() !== "NOT_SET" is true, regardless of anything about ql2, which is definitely wrong, because you haven't done a comparison between two elements from the array.

Here's my solution:

function sortStringsLast<T>(arr: T[], key: (x: T) => string | number): T[] {
    return arr.sort((x, y) => {
        const xKey = key(x), yKey = key(y);
        if(typeof xKey === 'string') {
            return typeof yKey === 'string' ? 0 : 1;
        } else {
            return typeof yKey === 'string' ? -1 : xKey - yKey;
        }
    });
}

I am not sure from your code exactly how you are deriving a sorting key that is either a string or a number, so I wrote a function accepting a key parameter to derive the sorting keys however you want for your own data. Note that when xKey is a string, you only want to return 0 when yKey is also a string; otherwise we return 1 to indicate that x should appear after y in sorted order, because xKey is a string and yKey is a number.

If you did want the strings to be in some specific order, you could easily replace the 0 in the above function with some other comparator, e.g. xKey.localeCompare(yKey).

Test:

const arr = [1, 'foo', 4, 'bar', 3, 'baz', 2];

// [1, 2, 3, 4, "foo", "bar", "baz"]
console.log(sortStringsLast(arr, x => x));

Playground Link

  •  Tags:  
  • Related