Javascript 按具有多种含义的对象值(组)仅使用比较器进行排序

标签 javascript sorting

我有一些数据格式如下:

var data = [
        { id: 1, name:  "Netherlands", population: 17},
        { id: 1.1, name: "Rotterdam", population: 4},
        { id: 1.2, name: "Amsterdam", population: 2},
        { id: 2, name:  "USA", population: 350},
        { id: 3, name: "Germany", population: 55},
        { id: 3.1, name: "Berlin", population: 4},
        { id: 3.2, name: "Stuttgard", population: 3},
        { id: 3.3, name: "Cologne", population: 3},
        { id: 4, name: "UK", population: 60},
        { id: 5, name: "Canada", population: 30},
        { id: 5.1, name: "Ottawa", population: 2},
    ];

基本上名称可以是城市或国家。国家被标识为整数,其城市被标识为 0.1。每个国家可以有0-3个城市。

是否可以为 Array.prototype.sort 编写一个比较器函数,例如按字母顺序对国家/地区进行排序,然后按城市进行排序,但保持国家/城市分组完整,并且不会事先改变数据数组?这可能吗?如果没有,为什么?如果不可能,我仍然有兴趣知道如何事先改变数组,尽管这对我来说需要更多的回溯,而且并不理想。

因此按名称字母顺序排序将给出:

var data = [
    { id: 5, name: "Canada", population: 30},
    { id: 5.1, name: "Ottawa", population: 2},
    { id: 3, name: "Germany", population: 55},
    { id: 3.1, name: "Berlin", population: 4},
    { id: 3.3, name: "Cologne", population: 3},
    { id: 3.2, name: "Stuttgard", population: 3},
    { id: 1, name:  "Netherlands", population: 17},
    { id: 1.2, name: "Amsterdam", population: 2},
    { id: 1.1, name: "Rotterdam", population: 4},
    { id: 4, name: "UK", population: 60},
    { id: 2, name:  "USA", population: 350},
];

这是一个笨蛋,我已经走了多远:

http://plnkr.co/edit/vPTaoh

我不明白为什么/如何 array.prototype.sort 选择要比较的值,所以我不确定该往哪个方向走。任何帮助将不胜感激。

最佳答案

I don't understand why/how Array.prototype.sort picks which values to compare

它从数组中任意选取它们,具体取决于它内部使用的排序算法。您的比较函数需要适用于所有值。

Is it possible to write a comparator function for Array.prototype.sort where it sorts for instance, the countries alphabetically, then by their cities but keeps the country/city grouping intact, and does not mutate the data array beforehand?

不,这不可能(轻易)实现。要比较两个项目,您始终需要首先比较它们的国家/地区,但当项目是城市时这是不可能的:没有从城市到国家/地区名称的链接。
您需要找到一种方法来首先查找它(从技术上讲,给定 id 是可能的,但您必须事先构造一个查找表,否则在排序期间会低效地搜索数组)。

将数据更改为以下结构会对自己有利:

var data = [
    {id: 1, name:  "Netherlands", population: 17, cities: [
        {id: 1.1, name: "Rotterdam", population: 4},
        {id: 1.2, name: "Amsterdam", population: 2}
    ]},
    {id: 2, name: "USA", population: 350, cities: []},
    {id: 3, name: "Germany", population: 55, cities: [
        {id: 3.1, name: "Berlin", population: 4},
        {id: 3.2, name: "Stuttgard", population: 3},
        {id: 3.3, name: "Cologne", population: 3}
    ]},
    {id: 4, name: "UK", population: 60, cities: []},
    {id: 5, name: "Canada", population: 30, cities: [
        {id: 5.1, name: "Ottawa", population: 2}
    ]}
];

然后使用标准方法仅对国家/地区及其内的城市进行排序。

关于Javascript 按具有多种含义的对象值(组)仅使用比较器进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39625178/

相关文章:

javascript - 如何对触发最少回流的 DOM 元素进行排序?

arrays - 以有效的方式排序和合并两个数组?

Java Multimap 具有自然排序的键,但集合按添加元素的顺序排序

java - 如何在Java中保持原始排序不变的情况下基于比较器执行排序

javascript - Wordpress - 翻译 javascript 或 jquery 中的字符串

javascript - ajax调用后如何重新初始化Owl Carousel?

javascript - 条件显示 knockout js

javascript - 按键事件未在移动设备上运行

javascript - 如何在不手动一一添加的情况下为组件中的每个元素绑定(bind)相同的事件?

algorithm - 通过一系列反转对数组进行排序的最有效方法是什么?