按自定义订单排序

问题描述 投票:0回答:5

我想知道如何按自定义顺序而不是按字母顺序对数组进行排序。想象你有这个数组/对象:

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"
}];

这里有3种不同的类型:水果、蔬菜和糖果。现在我想对这个数组进行排序,并确保所有水果都在前面,糖果在水果后面,蔬菜在最后。每种类型都需要按字母顺序对它们的项目进行排序。我们将使用像

sortArrayOnOrder ( ["fruit","candy","vegetable"], "name" );
这样的函数,所以基本上,排序后你会得到这个数组:

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"
}];

有人知道如何为此创建脚本吗?

javascript arrays
5个回答
72
投票

Cerbrus 代码的改进版本:

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);
});

17
投票

试试这个:

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.
        }
    }
);

此外,您的对象声明不正确。而不是:

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

用途:

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

因此,将

=
符号替换为
:


3
投票

对于想要简单地按自定义顺序对字符串数组进行排序的人,请尝试以下功能:

// 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);

这将按照指定的顺序对数组进行排序。该函数的两个示例输入/输出:

示例1:

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

示例2:

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

0
投票

let arr =[
  {
    "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"
  }
];

const sortObjectArrayByStringKey = (arr = [], key = '') => {
  // 1. sort string keys ✅
  const sortKeys = arr.map(obj => obj[key]).sort();
  console.log(`sortKeys =`, JSON.stringify(sortKeys));
  let result = [];
  for(let sortKey of sortKeys) {
    // 2. custom order objetcs with sortKey 🚀
    result.push(arr.find(obj => obj[key] === sortKey))
  }
  console.log(`result =`, JSON.stringify(result));
  return result;
}

// groups
function sortArrayOnOrder(arr, types, key) {
  let result = [];
  for(let type of types) {
    let temp = arr.filter(obj => obj.type === type);
    result.push(...sortObjectArrayByStringKey(temp, key));
  }
  console.log(`result =`, JSON.stringify(result));
  return result;
}

sortArrayOnOrder(arr, ["fruit","candy","vegetable"], "name");
// result = [{"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"}]

enter image description here


-4
投票

Array.sort 接受排序函数,您可以在其中应用自定义排序逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.