1

priority is to order by highest value, if two or more keys has same value then keys should be sorted alphabetically.

Tried below logic, worked for me. Looking for better approach.**


//Input Object:
let myObj = {
    hello : 1, // key is Alpha, value is Number
    zello : 5,
    pillow : 6,
    there : 6,
    here : 6,
    peppa : 2,
    boww : 5
};

let flag = true, initialCount=0, finalCount=0, newArr = [];
const keysSorted = Object.keys(myObj).sort((a,b) => myObj[b]-myObj[a]);

for(let i=0; i<keysSorted.length; i++) {
    if(myObj[keysSorted[i]] === myObj[keysSorted[i+1]]) {
        if(flag) {
            initialCount = i;
            flag = false;
        }
    } else {
        if(!flag) {
            finalCount = i;
        }
        if(flag) {
            newArr.push(keysSorted[i]);
        } else {
            let tempArr = keysSorted.slice(initialCount, finalCount+1);
            tempArr.sort();
            newArr.splice(initialCount, 0, ...tempArr);
        }
        flag = true;
        initialCount = 0;
        finalCount = 0;

    }
    
}

console.log(newArr); 
//Output:
//["here", "pillow", "there", "boww", "zello", "peppa", "hello"]

3 Answers 3

1

The below function will simplify your current approach.

function sortObj(obj) {
    return Object.entries(obj)
        .sort((a, b) =>
            a[1] !== b[1] ?
            b[1] - a[1] :
            b[0] < a[0] ? 1 : -1
        )
        .map(e => e[0]);
}

Working Demo

function sortObj(obj) {
    return Object.entries(obj)
        .sort((a, b) =>
            a[1] !== b[1] ?
            b[1] - a[1] :
            b[0] < a[0] ? 1 : -1
        )
        .map(e => e[0]);
}

let myObj = {
    hello : 1, // key is Alpha, value is Number
    zello : 5,
    pillow : 6,
    there : 6,
    here : 6,
    peppa : 2,
    boww : 5
};

console.log(sortObj(myObj));

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

Comments

0

There is a rather new (es2017) feature, Object.entries() that could help out. It returns the object as array and makes it easy to processs.

// returns [["hello",1],["zello",5],["pillow",6],["there",6],["here",6],["peppa",2],["boww",5]]
console.log(Object.entries(myObj));

Using Object.entries(), we can acces the name and value by index:

function sortByPriorityDescAndNameAsc(i, j) {
  let priority = (i[1] - j[1]) * -1;
  let name = i[0].localeCompare(j[0]);
  // uses sort by name if priority is zero
  return priority || name;
}
// returns ["here", "pillow", "there", "boww", "zello", "peppa", "hello"]
Object.entries(myObj).sort(sortByPriorityDescAndName).map(i => i[0]);

We could shorten the code even further but I've kept it for clarity.

Comments

0

The way to sort by two conditions is to return a negative or positive value if the first sort values aren't the same. If they are the same, you do that logic using the second value to sort by instead. And if those are the same, you return 0.

let myObj = {
    hello : 1, // key is Alpha, value is Number
    zello : 5,
    pillow : 6,
    there : 6,
    here : 6,
    peppa : 2,
    boww : 5
};

const entries = Object
  .entries(myObj)
  .sort(([keyA, valueA], [keyB, valueB]) => {
    return (valueA === valueB)
      ? keyA.localeCompare(keyB); // Return value is compatible with sort functions
      : valueB - valueA;          // If B > A, then result is positive meaning A goes second
  })
  .map(([key, value]) => key);         // Get just the keys

console.log(entries);

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.