0

I have an array of objects and I'm trying to sort their information by type and code. My goal is to first get as lines whose type type = true and then sort by the code in ascending order.

Demo

I tried this, but he's putting the fake ones on top and doesn't sort the code in ascending order.

Can anyone help me?

.TS

  data = [{
    cod: 1.19,
    type: true
  },
  {
    cod: 1.13,
    type: true
  },
  {
    cod: 1.01,
    type: true
  },
  {
    cod: 1.1,
    type: false
  },
  {
    cod: 1.2,
    type: true
  },
  {
    cod: 2.19,
    type: false
  },
  {
    cod: 3.29,
    type: true
  },
  {
    cod: 5.19,
    type: false
  },
  {
    cod: 1.7,
    type: false
  },]

  ngOnInit(){
    this.data.sort(function (x, y) {
      return (x.type === y.type) ? 0 : x ? -1 : 1;;
  });

  console.log(this.data)
  }
3
  • So, you want to sort by type, then by code, with type == true first? return x.type ? -1 : x.cod - y.cod; Commented Aug 9, 2021 at 18:03
  • @HereticMonkey Yes, that's right Commented Aug 9, 2021 at 18:07
  • Does this answer your question? Sort array of objects by booleans, then by numbers (javascript) Commented Aug 9, 2021 at 18:14

2 Answers 2

1

Instead of starting with a one line if-statement. I prefer to use more lines of code to easier understand the logic which has to be performed

// return 1 if x has more value/larger than y
// return -1 if x has less value/smaller than y
data.sort(function (x, y) {
  // type has priority over cod. So cod can be ignored if type is different for x and y
  if (x.type == true && y.type == false) {
    return 1;
  }
  if (x.type == false && y.type == true) {
    return -1;
  }
  // If type is the same for y and x, compare the cod value instead!
  if (x.type == y.type) {
    if (x.cod > y.cod) {
      return 1;
    }
    if (x.cod < y.cod) {
      return -1;
    }
  }
  // Return 0 if they have the exact same
  return 0;
});

Reducing the code a bit by subtracting the cod numbers instead. Negative means y.cod is larger, positive mean x.cod is larger. zero means they are equal.

data.sort(function (x, y) {
  if (x.type == true && y.type == false) {
    return 1;
  }
  if (x.type == false && y.type == true) {
    return -1;
  }
  // If type is the same for y and x, compare the cod value instead!
  if (x.type == y.type) {
      // Can be condensed to a single subtraction
      return x.cod - y.cod;
  }
});

Can be improved further with fewer comparisons

data.sort(function (x, y) {
  // these are equivalent to the first two if-statements in the code blocks above.
  if (x.type && !y.type) return 1;
  if (!x.type && y.type) return -1;
  // if none of above has been triggered, the types are equal and cod should be compared.
  return x.cod - y.cod;
});

And as @Eliseo suggested, it can be condensed with ternary operators which will reduce execution time.

data.sort(function (x,y) {
  return !x.type && y.type ? 1 : (x.type && !y.type ? -1 : x.cod-y.cod);
});

For understanding it's easier to start with the most straight forward one where the logic can be followed easily. Then from there see what can be done to simplify it.

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

5 Comments

This is already answered in the duplicate. Feel free to add your answer to the duplicate if you feel it adds something.
data.sort((x,y)=>!x.type &&y.type?1:x.type && !y.type?-1:x.cod-y.cod)
@Eliseo I don't see any reason for complicating it to a single line. It just becomes way harder to understand what's going on at a glance.
it's faster, but true, is harder to understand :(
I just compared them it, it's faster indeed. I'll update the answer with a third version like yours. At least I found yours easier to grasp after I implemented my longer version.
0

I would prefer something like this:

var sorted = data
    .sort(function(x, y) { 
        return x.cod - y.cod;
    })
    .sort(function(x, y) {
        return y.type - x.type;
    });

Edit: better code formatting.

2 Comments

This is already answered in the duplicate. Feel free to add your answer to the duplicate if you feel it adds something.
Ouh, I'm sorry at this point. Anyway, I'm not going to delete this answer, because I consider this the cleanest way to do that stuff.

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.