14

I have an array of objects I need to sort on a custom function. Since I want to do this several times on several object attributes, I'd like to pass the key name for the attribute dynamically into the custom sort function:

function compareOnOneFixedKey(a, b) {
    a = parseInt(a.oneFixedKey)
    b = parseInt(b.oneFixedKey)
    if (a < b) return -1
    if (a > b) return 1
        return 0
}
    
arrayOfObjects.sort(compareByThisKey)

This should become something like:

function compareOnKey(key, a, b) {
    a = parseInt(a[key])
    b = parseInt(b[key])
    if (a < b) return -1
    if (a > b) return 1
        return 0
}
arrayOfObjects.sort(compareOn('myKey'))

Can this be done in a convenient way?

4 Answers 4

17

You may add a wrapper:

function compareOnKey(key) {
    return function(a, b) {
        a = parseInt(a[key], 10);
        b = parseInt(b[key], 10);
        if (a < b) return -1;
        if (a > b) return 1;
        return 0;
    };
}

arrayOfObjects.sort(compareOnKey("myKey"));
Sign up to request clarification or add additional context in comments.

Comments

11

You would need to partially apply the function, e.g. using bind:

arrayOfObjects.sort(compareOn.bind(null, 'myKey'));

Or you just make compareOn return the actual sort function, parametrized with the arguments of the outer function (as demonstrated by the others).

6 Comments

Besides the method is good it still has compatibility problems.
@VisioN: …but makes so many thing easier :-) For anybody considering supporting old IEs, the linked MDN page contains a shim
@VisioN .bind is supported in IE9 and this requires mimimal refactoring of current code
On chrome, shim added, i cannot make this work function refacrtored as: function compareOn(a, b, key) { a = parseInt(a[key], 10) b = parseInt(b[key], 10) if (a < b) return -1 if (a > b) return 1 return 0 }
@paolo: If you want to use partial application, the key argument needs to come first (as in your second snippet).
|
5

Yes, have the comparator returned from a generator which takes a param which is the key you want

function compareByProperty(key) {
    return function (a, b) {
        a = parseInt(a[key], 10);
        b = parseInt(b[key], 10);
        if (a < b) return -1;
        if (a > b) return 1;
        return 0;
    };
}
arrayOfObjects.sort(compareByProperty('myKey'));

compareByProperty('myKey') returns the function to do the comparing, which is then passed into .sort

1 Comment

working well, but choosen the .bind() way for its flexibility. thank you for refactoring my code with the base 10 in parseInt :)
1

const objArr = [{
    name: 'Z',
    age: 0
  }, {
    name: 'A',
    age: 25
  }, {
    name: 'F',
    age: 5
}]
  
const sortKey = {
    name: 'name',
    age: 'age'
}

const sortArr = (arr, key) => {
    return arr.sort((a, b) => {
        return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0
    })
}
  
console.log("sortKey.name: ", sortArr(objArr, sortKey.name))
console.log("sortKey.age: ", sortArr(objArr, sortKey.age))

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.