4

I'm able to successfuly find out the largest values in the object, however. There is a problem, and that is inability to display the associated key with that value.

var obj = {
    t1: 1,
    t2: 33,
    t3: 10,
    t4: 9,
    t5: 45,
    t6: 101
    //...
}

// create an array
var arr = [];

// loop through the object and add values to the array
for (var p in obj) {
  arr.push(obj[p]);
}

// sort the array, largest numbers to lowest
arr.sort(function(a,b){return b - a});

// grab the first 10 numbers
var firstThree = arr.slice(0, 3);
console.log(firstThree);

It can display the top values, however i'm having a hard time to display keys with that.

The result should be like

var result = {
    t6: 101,
    t5: 45,
    t2: 33

}
Alexandre Elshobokshy
  • 10,720
  • 6
  • 27
  • 57
Stas
  • 605
  • 6
  • 21
  • Do you need `result` to be the *same* object as `obj` (with the other keys removed), or an entirely new object (so, you now have two)? – VLAZ Jan 28 '19 at 12:00
  • Whatever is the most efficient way, is the way im after, I just want to send and object with highest values and associated keys with that – Stas Jan 28 '19 at 12:03
  • Possible duplicate of [Sorting JavaScript Object by property value](https://stackoverflow.com/questions/1069666/sorting-javascript-object-by-property-value) – Ayman Safadi Jan 28 '19 at 12:07
  • not really a dublicate, i think here is more straightforward and more flexible – Stas Jan 28 '19 at 12:11

8 Answers8

8

You could get the entries, sort and slice them and build a new object by assigning mapped objects to a single object.

var object = { t1: 1, t2: 33, t3: 10, t4: 9, t5: 45, t6: 101 },
    result = Object.assign(                      // collect all objects into a single obj
        ...Object                                // spread the final array as parameters
            .entries(object)                     // key a list of key/ value pairs
            .sort(({ 1: a }, { 1: b }) => b - a) // sort DESC by index 1
            .slice(0, 3)                         // get first three items of array
            .map(([k, v]) => ({ [k]: v }))       // map an object with a destructured
    );                                           // key/value pair

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Pretty hard to understand even with comments, but it works, i tried to sit with it and play with console.log but still dont really get ho it works, like why sort has {1:a}, {1:b}. – Stas Jan 28 '19 at 13:19
  • this is a [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) with an array for both parameters, where the arrays are destructured to an object with a key `1` and renamed to `a` or `b`. for a single array, it looks like `['t6', 101]` and the result is `101`. – Nina Scholz Jan 28 '19 at 13:22
  • ahw, now it makes sense. I knew about destructing assignment, but only used it with arrays or imports before :) thanks Nina – Stas Jan 28 '19 at 13:29
2

You can push objects into array instead of values, so that you can store keys

var obj = {
    t1: 1,
    t2: 33,
    t3: 10,
    t4: 9,
    t5: 45,
    t6: 101
}

// create an array
var arr = [];

// loop through the object and add values to the array
for (var p in obj) {
  arr.push({key: p, value: obj[p]});
}

// sort the array, largest numbers to lowest
arr.sort(function(a,b){return b.value - a.value});

// grab the first 10 numbers
var firstThree = arr.slice(0, 3);
console.log(firstThree);
sridhar..
  • 1,945
  • 15
  • 19
2

You could push to your array an object containing the key and value association arr.push({p: obj[p]})

var obj = {
  t1: 1,
  t2: 33,
  t3: 10,
  t4: 9,
  t5: 45,
  t6: 101
}

// create an array
var arr = [];

// loop through the object and add values to the array
for (var p in obj) {
  arr.push({
    p: obj[p]
  });
}

// sort the array, largest numbers to lowest
arr.sort(function(a, b) {
  return b - a
});

// grab the first 10 numbers
var firstThree = arr.slice(0, 3);
console.log(firstThree);

Nothing fancy but does the job :-)

Alexandre Elshobokshy
  • 10,720
  • 6
  • 27
  • 57
1

you can do something like this

var obj = {
  t1: 1,
  t2: 33,
  t3: 10,
  t4: 9,
  t5: 45,
  t6: 101
};

// create an array
var arr = [];

// loop through the object and add values to the array
for (var p in obj) {
  arr.push({ key: p, val: obj[p] });
}

// sort the array, largest numbers to lowest
arr.sort(function(a, b) {
  return b.val - a.val;
});

// grab the first 10 numbers
var firstThree = arr.slice(0, 3);
console.log(...firstThree);
WPFUser
  • 1,145
  • 7
  • 24
1

You can first get the values of that object and sort it. Then loop over to the key-value of that object using Object.entries() and determine the key of that value which belong to top 3 values:

var obj = {
    t1: 1,
    t2: 33,
    t3: 10,
    t4: 9,
    t5: 45,
    t6: 101
};

var values = Object.values(obj).sort((a,b) => b-a).slice(0,3);
let resultObj = {};
Object.entries(obj).forEach((item) => {
  if(values.indexOf(item[1]) !== -1){
    resultObj[item[0]] = item[1];
  }
});
console.log(resultObj);

Also note that the key ordering in object does not really matter when you work with object, so

{
    t6: 101,
    t5: 45,
    t2: 33

}

is similar to

{
    t2: 33,
    t5: 45,
    t6: 101

}
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
1

Alternative solution using lodash

_.chain(object)
    .map((value, key) => ({value, key}))
    .sortBy("value")
    .reverse()
    .take(3)
    .reduce((acc, item) => ({ ...acc, [item.key]: item.value}), {})
    .value();
Rafael Hovsepyan
  • 781
  • 8
  • 14
0
var obj = {
  t1: 1,
  t2: 33,
  t3: 10,
  t4: 9,
  t5: 45,
  t6: 101
};

const sortedKey = Object.keys(obj).sort((a,b)=>{
if(obj[a] > obj[b]) return -1;
if(obj[a] < obj[b]) return 1;
return 0;
})
//print top three key -- val
for(let i=0; i< 3; i++) console.log(sortedKey[i], '--', obj[sortedKey[i]])
Arshpreet Wadehra
  • 993
  • 2
  • 9
  • 23
0

Objects key are not guaranteed to remain in order, so don't trust that.

It's safe though to create and use an array for that:

const top10KeyValArr = Object.entries(obj).sort(([_k1, val1], [_k2, val2])=> val2 - val1).slice(0, 3);

Then you can do what you want with it and it will remain in that order.

estani
  • 24,254
  • 2
  • 93
  • 76