35

I was wondering how I can sort an array on a custom order, not alphabetical. Imagine you have this array/object:

var somethingToSort = [{
    type: "fruit",
    name: "banana"
}, {
    type: "candy",
    name: "twix"
}, {
    type: "vegetable",
    name: "broccoli"
}, {
    type: "vegetable",
    name: "carrot"
}, {
    type: "fruit",
    name: "strawberry"
}, {
    type: "candy",
    name: "kitkat"
}, {
    type: "fruit",
    name: "apple"
}];

In here we have 3 different types: fruit, vegetable and candy. Now I want to sort this array, and make sure that all fruits are first, candies come after fruits, and vegetables be last. Each type need their items to be sorted on alphabetical order. We will use a function like sortArrayOnOrder ( ["fruit","candy","vegetable"], "name" ); So basically, you would end up with this array after sorting:

var somethingToSort = [{
    type: "fruit",
    name: "apple"
}, {
    type: "fruit",
    name: "banana"
}, {
    type: "fruit",
    name: "strawberry"
}, {
    type: "candy",
    name: "kitkat"
}, {
    type: "candy",
    name: "twix"
}, {
    type: "vegetable",
    name: "broccoli"
}, {
    type: "vegetable",
    name: "carrot"
}];

Anyone an idea how to create a script for this?

4

4 回答 4

53

Improved version of Cerbrus' code:

var ordering = {}, // map for efficient lookup of sortIndex
    sortOrder = ['fruit','candy','vegetable'];
for (var i=0; i<sortOrder.length; i++)
    ordering[sortOrder[i]] = i;

somethingToSort.sort( function(a, b) {
    return (ordering[a.type] - ordering[b.type]) || a.name.localeCompare(b.name);
});
于 2013-02-14T10:31:59.533 回答
9

Try this:

var sortOrder = ['fruit','candy','vegetable'];   // Declare a array that defines the order of the elements to be sorted.
somethingToSort.sort(
    function(a, b){                              // Pass a function to the sort that takes 2 elements to compare
        if(a.type == b.type){                    // If the elements both have the same `type`,
            return a.name.localeCompare(b.name); // Compare the elements by `name`.
        }else{                                   // Otherwise,
            return sortOrder.indexOf(a.type) - sortOrder.indexOf(b.type); // Substract indexes, If element `a` comes first in the array, the returned value will be negative, resulting in it being sorted before `b`, and vice versa.
        }
    }
);

Also, your object declaration is incorrect. Instead of:

{
    type = "fruit",
    name = "banana"
}, // etc

Use:

{
    type: "fruit",
    name: "banana"
}, // etc

So, replace the = signs with :'s.

于 2013-02-14T10:27:29.407 回答
1

For people looking to simply sort an array of strings in a custom order, try this function below:

// sorting fn
const applyCustomOrder = (arr, desiredOrder) => {
  const orderForIndexVals = desiredOrder.slice(0).reverse();
  arr.sort((a, b) => {
    const aIndex = -orderForIndexVals.indexOf(a);
    const bIndex = -orderForIndexVals.indexOf(b);
    return aIndex - bIndex;
  });
}

// example use
const orderIWant = ['cat', 'elephant', 'dog'];
const arrayToSort = ['elephant', 'dog', 'cat'];


applyCustomOrder(arrayToSort, orderIWant);

This will sort the array in the order specified. Two sample input / outputs to this function:

Example 1:

const orderIWant = ['cat', 'elephant', 'dog'] 
const arrayToSort = ['mouse', 'elephant', 'dog', 'cat'];
applyCustomOrder(arrayToSort, orderIWant); 
console.log(arrayToSort); // ["cat", "elephant", "dog", "mouse"]

Example 2:

const orderIWant = ['cat', 'elephant', 'dog'];
const arrayToSort = ['mouse', 'elephant', 'rabbit', 'dog', 'cat'];
applyCustomOrder(arrayToSort, orderIWant); 
console.log(arrayToSort); /* ["cat", "elephant", "dog", "mouse", 
"rabbit"] */
于 2020-08-17T19:33:23.790 回答
-3

Array.sort accepts a sort function where you can apply custom sorting logic.

于 2013-02-14T10:23:34.247 回答