本文介绍了Javascript仅具有Comparartor的具有多个含义(组)的对象值排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据格式如下:

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

基本名称可以是城市或国家.将国家标识为整数,将其城市标识为1.每个国家可以拥有0-3个城市.

Basically name can be either city or country. Countries are identified as whole numbers and their cities as .1. Each country can have 0-3 cities.

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

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? Is this possible? If not, why? If it is not possible, I'd still be interested to know how to do this mutating the array beforehand, though it will require a lot more backtracking for me, and is not ideal.

因此,按名称的字母顺序排序将得出:

So sorting alphabetically by name would give:

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

这是一个小矮人,我走了多远:

Here is a plunker, with how far I have gotten:

http://plnkr.co/edit/vPTaoh

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

I don't understand why/how array.prototype.sort picks which values to compare, so I'm not sure what direction to go. Any help would be greatly appreciated.

推荐答案

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

It picks them arbitrarily from the array, depending on what sorting algorithm it uses internally. Your comparison function needs to work on all values.

否,这不可能(轻松).要比较两个项目,您总是需要首先比较他们的国家/地区,但是当该项目是城市时,这是不可能的:城市与国家/地区名称之间没有链接.
您需要先找到一种方法来查找(技术上可以使用id,但是您必须事先构造一个查找表,或者在排序过程中搜索数组效率低下).

No, this is not (easily) possible. To compare two items, you always need to compare their countries first, but that's not possible whent the item is a city: there is no link from the city to the country name.
You would need to find a way to look this up first (technically it's possible given the id, but you have to construct a lookup table beforehand or inefficiently search the array during sorting).

通过将数据更改为以下结构,您将对自己有所帮助:

You would do yourself a favour by changing your data to the following structure:

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

然后使用标准方法仅对国家和其中的城市进行排序.

And then simply sort the countries only and the cities within them using the standard approach.

这篇关于Javascript仅具有Comparartor的具有多个含义(组)的对象值排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 14:30