2

I'm trying to sort an array of objects by its values and return the 3 keys with the highest value in descending order. The array is:

let obj = [
{'tom':4},
{'bill':5},
{'tina':6},
{'tim': 3}]

Solution I'm looking for: ['tina', 'bill', 'tom']

In case, there are more than three values, that fulfill the condition I would like to list them as well, like:

let obj = [
{'tom':4},
{'bill':5},
{'tina':6},
{'tim': 3},
{'jim':4]

Solution I'm looking for: ['tina', 'bill', 'tom', 'jim']

I tried to do something like:

Object.entries(obj).sort((a,b) => b[1] - a[1]).map(value => ({[value[0]]: value[1]}))

but couldn't figure out the right approach.

2
  • Will each object always only have 1 key? Commented Jul 30, 2021 at 8:12
  • yes, each object will always only have 1 key Commented Jul 30, 2021 at 8:19

4 Answers 4

2

let obj = [{
    'tom': 4
  },
  {
    'bill': 5
  },
  {
    'tina': 6
  },
  {
    'tim': 3
  },
  {
    'jim': 4
  }
]

let result = obj.map(object => {
  for (name in object) {
    return [name, object[name]]
  }
}).sort((a, b) => b[1] - a[1]).map(object => object[0])

console.log(result)

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

Comments

2
  1. First sort the array of objects by their values, (using .sort and Object.values.)
  2. Select the values of the top 3 items, (using .slice, .map and Object.values.)
  3. Select all the items from the original array that have values in the top 3 array, (using .reduce)

You should end up with an array of keys that have the top 3 highest values.

Here's what that looks like:

let obj = [
    {
        tom: 4,
    },
    {
        bill: 5,
    },
    {
        tina: 6,
    },
    {
        tim: 3,
    },
    {
        jim: 4,
    },
];

// An array of values of the Top 3 sorted objects
let top3 = obj
    .map((obj) => Object.values(obj)[0])
    .sort((a, b) => b - a)
    .slice(0, 3);
    

// An array the Top Keys that are found in t3
let topKeys = obj.reduce((acc, curr) => {
    if (top3.includes(Object.values(curr)[0])) acc.push(Object.keys(curr)[0]);
    return acc;
}, []);

console.log(topKeys);

Comments

1

Step 1.

Using Array#reduce to create an object that looks like {[value: number]: Array<string>}, which will be automatically sorted due to the default object key sorting.

Step 2.

Using Object.values to get the list of values of the {[value: number]: Array<string>} object.

Step 3.

Using Array#slice to get the last 3 items.

Step 4.

Using Array#flat to convert the array from Array<Array<string>> to Array<string>.

let obj = [
  { 'tom': 4 },
  { 'bill': 5 },
  { 'tina': 6 },
  { 'tim': 3 },
  { 'jim': 4 }
];

var sortedObj = obj.reduce(function(result, item) {
  // get the name and value of the current object
  var key = Object.keys(item)[0], value = item[key];
  // get the list of names for that value
  var list = result[value];
  // if this is the first occurence of the value, create the array
  if (!list) result[value] = list = [];
  // add the name to the array
  list.push(key);
  return result;
}, {});

var sortedList = Object.values(sortedObj);

var last3 = sortedList.slice(sortedList.length - 3);

var result = last3.flat();

console.log(result);

Comments

1

You could

  • map the entries of the object,
  • sort the 2D array of entries based on the first entry's value
  • map to get the first value of each object

const input = [{ tom: 4 }, { bill: 5 }, { tina: 6 }, { tim: 3 }];

const output = input
                .map(Object.entries)
                .sort(([a], [b]) => b[1] - a[1])
                .map(([[name]]) => name);

console.log(output)

Comments

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.