Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to 'sort' two objects based on number of occurrences of elements in an array field?

If I have two objects, and they both have two array fields within them, like so:

const list1 = {
  name: 'list-1',
  fruits: ['banana', 'strawberry', 'cherry'],
  vegs: ['lettuce', 'avocado', 'beans']
};

const list2 = {
  name: 'list-2',
  fruits: ['banana', 'apple', 'orange', 'watermelon'],
  vegs: ['potato', 'avocado', 'onion', 'cabbage']
};

And then, I pass in two arrays, one of fruits, and one of vegetables, e.g.:

const fruits = ['banana', 'strawberry'];
const vegetables = ['potato', 'lettuce', 'avocado'];

How can I order the objects, so that has the one with most number of fruits and vegetables (based on the passed in arrays) is on top?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

In this case that’d be list1, since it has both "banana" and "strawberry" in fruits, and also has "lettuce" and "avocado" in vegs (i.e. 4 matches in total), whereas list2 only has 2 hits in total.

Not sure if that makes a lot of sense, but what would be the most efficient way to order the two objects based on the arrays?

>Solution :

First, you’ll need to define an intersection function – a function that, given two lists, returns a new list containing only the elements found in both lists. There’s a very comprehensive answer here if you want to write your own version, or plenty of libraries that you can use to accomplish this (e.g. Ramda or Lodash). You could do this within your sort function, but it’s not hard to imagine that you’d need it again in other contexts so it probably makes sense to have a reusable function.

Assuming you’ve got an implementation of this function available, you can now write a custom compare function that can be used to order objects shaped like list1 and list2 according to the rules you’ve provided, something like this:

const compareByTotal = (a, b) => {
    const aTotal = intersection(a.fruits, fruits).length + intersection(a.vegs, vegetables).length;
    const bTotal = intersection(b.fruits, fruits).length + intersection(b.vegs, vegetables).length;
 
    return bTotal - aTotal;
}

Finally, you can use this function as a parameter when calling sort to produce a sorted list of these objects:

[list1, list2].sort(compareByTotal);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading