0

I'm trying to sort my javascript array of objects

ownerName     dogCode   dogName
Bob           5         Rex
John        
Alisha        3         Moon
Darren        4         Boss  
Josh
Cerq

I want it to be sort first by dogCode (just if exists or not, ignoring the number), than by ownerName, and finally by dogName, like this:

ownerName     dogCode   dogName
Alisha        3         Moon
Bob           5         Rex    
Darren        4         Boss 
Cerq
John        
Josh

I tried this:

data.sort(function (a, b) {
    if (a.dogCode < b.dogCode || !a.dogCode) return 1;
    if (a.dogCode > b.dogCode || !b.dogCode) return -1;
    if (a.ownerName < b.ownerName || !a.ownerName) return 1;
    if (a.ownerName > b.ownerName || !b.ownerName) return -1;
    if (a.dogName < b.dogName || !a.dogName) return 1;
    if (a.dogName > b.dogName || !b.dogName) return -1;
     return 0;
});

Aparenttely, It is sorting by dogCode correctly, but not by name/dogName. How can I do this?

EDIT: here is my json object:

{
  "data": [
    {
      "ownerName": "Bob",
      "dogCode": "5",
      "dogName": "Rex"
    },
    {
      "ownerName": "John"
    },
    {
      "ownerName": "Alisha",
      "dogCode": "3",
      "dogName": "Moon"
    },
    {
      "ownerName": "Darren",
      "dogCode": "4",
      "dogName": "Bos"
    },
    {
      "ownerName": "Josh"
    },
    {
      "ownerName": "Cerq"
    }
  ]
}
3
  • can you post your array Commented Nov 13, 2020 at 17:41
  • do you have zero vlaues for dogCode? do you have some data for testing? Commented Nov 13, 2020 at 17:41
  • I edited my question adding my json object Commented Nov 13, 2020 at 17:49

2 Answers 2

1

It may not be the most efficient way, but I find the code below to be pretty understandable. Note that the sorts need applied in the opposite order from how you listed them.

const obj = {
  "data": [
    {
      "ownerName": "Bob",
      "dogCode": "5",
      "dogName": "Rex"
    },
    {
      "ownerName": "John"
    },
    {
      "ownerName": "Alisha",
      "dogCode": "3",
      "dogName": "Moon"
    },
    {
      "ownerName": "Darren",
      "dogCode": "4",
      "dogName": "Bos"
    },
    {
      "ownerName": "Josh"
    },
    {
      "ownerName": "Cerq"
    }
  ]
};

const byPropExists = prop => (a, b) => {
  if (a[prop] !== undefined && b[prop] === undefined) return -1;
  if (a[prop] === undefined && b[prop] !== undefined) return 1;
  return 0;
}
const byPropValue = prop => (a, b) => a[prop]?.localeCompare(b[prop])

// Note the reverse order of your sorts
console.log(obj.data
  .sort(byPropValue('dogName'))
  .sort(byPropValue('ownerName'))
  .sort(byPropExists('dogCode'))
);

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

Comments

0

You could take the delta of the check for undefined as sorting value and sort by delta of numbers or with String#localeCompare for strings.

const data = [{ ownerName: 'Bob', dogCode: 5, dogName: 'Rex' }, { ownerName: 'John' }, { ownerName: 'Alisha', dogCode: 3, dogName: 'Moon' }, { ownerName: 'Darren', dogCode: 4, dogName: 'Boss' }, { ownerName: 'Josh' }, { ownerName: 'Cerq' }];

data.sort((a, b) =>
    (a.dogCode === undefined) - (b.dogCode === undefined) ||
    (a.ownerName === undefined) - (b.ownerName === undefined) ||
    (a.dogName === undefined) - (b.dogName === undefined) ||

    (a.ownerName || '').localeCompare(b.ownerName || '') ||
    a.dogCode - b.dogCode ||
    (a.dogName || '').localeCompare(b.dogName || '')
);
   
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

5 Comments

Your code snippet has an error: "Uncaught ReferenceError: result is not defined"
In your code, "Bob" is after "Darren", so this is not the expected result
please add some more data to show how dogCode should be sorted.
You can ignore de dogCode value, it is just to know who has a dog.
you could play with your whole data set and move the less important sorting rules to the end of the function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.