按3个属性对javascript数组进行排序

Sorting javascript array by 3 properties

本文关键字:排序 数组 javascript 3个 属性      更新时间:2023-09-26

我有一个带有位置列表的数组。

我添加了3个属性,详细说明了每个位置与设置的起始位置的关系。

阵列中的每个位置都具有以下3个属性:

bearing (0 to 360 degrees)
humanFriendlyCompassHeading (North, North East, East etc)
distance (in km)

我能够通过方位对阵列进行排序,因此位置从0度到360度列出,并且人类友好的指南针方向是有序的,因此阵列中的前几个条目是北方,然后是东北、东方等。

然而,我希望对每个人类友好指南针的航向,即北、东北、东,从最近到最远的距离进行排序。

这就是我迄今为止使用下面提供的代码和比较功能所做的:

var myCmp = composeComparisons([sortArrayByBearing, sortArrayByHumanFriendlyCompassHeading, sortArrayByDistance]);
res.geonames.sort(myCmp);

function sortArrayByDistance(A, B)
{
return parseFloat(A.distance) - parseFloat(B.distance);
}
function sortArrayByBearing(A, B)
{
return parseFloat(A.bearing) - parseFloat(B.bearing);
}
//Used to sort results array by humanFriendlyCompassHeading
//usage: results.sort(sortArrayByHumanFriendlyCompassHeading);
//The sorting of humanFriendlyCompassHeading is realised with a map and look up for the value.
function sortArrayByHumanFriendlyCompassHeading(A, B) {
var DIRECTIONS = { North: 0, NorthEast: 1, East: 2, SouthEast: 3, South: 4, SouthWest: 5, West: 6, NorthWest: 7};
return         DIRECTIONS[A.humanFriendlyCompassHeading] - DIRECTIONS[B.humanFriendlyCompassHeading];
}

以下是我希望如何对数据进行排序的示例输出:

  • (514m,北部)诺丁汉特伦特大学艺术与设计学院

  • (北部695米)植物园,诺丁汉

  • (424米,东北)Archiam中心

  • (497米,东北)莎士比亚街卫斯理改革教堂

  • (795米,东北)诺丁汉市区

  • (796米,东北)诺丁汉维多利亚汽车站

  • (438米,东部)诺丁汉会议中心

这是原始数组的一部分。稍后,我将使用数组中返回的lat和lng值添加从我的起始位置开始的方位、距离和人类友好值:

         "summary":"The Diocese of Nottingham, England, is a Roman Catholic diocese of the Latin Rite which covers an area of 13,074 km², taking in the counties of Nottinghamshire (excluding the district of Bassetlaw), Leicestershire, Derbyshire, Rutland and Lincolnshire (...)",
     "elevation":65,
     "lng":-1.1572,
     "distance":"0.0685",
     "countryCode":"GB",
     "rank":84,
     "lang":"en",
     "title":"Roman Catholic Diocese of Nottingham",
     "lat":52.9545,
     "wikipediaUrl":"en.wikipedia.org/wiki/Roman_Catholic_Diocese_of_Nottingham"
  },
  {  
     "summary":"The Cathedral Church of St. Barnabas in the city of Nottingham, England, is a cathedral of the Roman Catholic church. It is the mother church of the Diocese of Nottingham and seat of the Bishop of Nottingham. (...)",
     "elevation":67,
     "feature":"landmark",
     "lng":-1.15708,
     "distance":"0.0703",
     "countryCode":"GB",
     "rank":82,
     "lang":"en",
     "title":"Nottingham Cathedral",
     "lat":52.95466,
     "wikipediaUrl":"en.wikipedia.org/wiki/Nottingham_Cathedral"
  },
  {  
     "summary":"The Albert Hall, Nottingham, is a City Centre Conference and Concert venue, situated in Nottingham, England. (...)",
     "elevation":61,
     "feature":"landmark",
     "lng":-1.1563944444444442,
     "distance":"0.1217",
     "countryCode":"GB",
     "rank":72,
     "lang":"en",
     "title":"Albert Hall, Nottingham",
     "lat":52.95441944444445,
     "wikipediaUrl":"en.wikipedia.org/wiki/Albert_Hall%2C_Nottingham"
  },
  {  
     "summary":"The Nottingham Playhouse is a theatre in Nottingham, Nottinghamshire, England. It was first established as a repertory theatre in the 1950s when it operated from a former cinema. Directors during this period included Val May and Frank Dunlop (...)",
     "elevation":67,
     "feature":"landmark",
     "lng":-1.1577,
     "distance":"0.1235",
     "countryCode":"GB",
     "rank":77,
     "lang":"en",
     "title":"Nottingham Playhouse",
     "lat":52.9537,
     "wikipediaUrl":"         en.wikipedia.org/wiki/Nottingham_Playhouseenter code here

要组成与Array.prototype.sort一起使用的比较函数,可以使用以下函数:

function composeComparisons(cmpFunctions) {
     return function (a, b) {
          for (var i = 0, result; i < cmpFunctions.length; i++) {
                result = cmpFunctions[i](a, b);
                if (result) {
                    return result;
                }
          }
          return 0;
     }
};

它将返回一个函数,将项目与每个比较函数进行比较,直到获得显著结果。

你会这样使用它:

// From most significant to least significant comparison function
var myCmp = composeComparisons([cmpByBearing, cmpByDistance, cmpByFriendliness]);
array.sort(myCmp);

作为提醒,如果a大于b,则比较函数cmp(a, b)返回正数;如果b大于a,则返回负数;如果项目相同,则返回0

您假定的排序顺序

  • 方位(0至360度)[此处无数据]
  • HumanFriendlyCompass标题
  • 距离(米)

可以通过具有以下功能的排序来实现。

该函数为每个排序组获取差异,如果差异相同(这是值0),则获取下一组,并根据差异的结果进行排序,依此类推

humanFriendlyCompassHeading(此处用compassDirection改写)的排序是通过映射和查找值来实现的。

var data = [
    { distance: 695, compassDirection: 'North', target: 'The Arboretum, Nottingham' },
    { distance: 497, compassDirection: 'NorthEast', target: 'Shakespeare Street Wesleyan Reform Chapel' },
    { distance: 438, compassDirection: 'East', target: 'Nottingham Conference Centre' },
    { distance: 514, compassDirection: 'North', target: 'Nottingham Trent University, School of Art and Design' },
    { distance: 795, compassDirection: 'NorthEast', target: 'Nottingham Urban Area' },
    { distance: 424, compassDirection: 'NorthEast', target: 'Archiam Centre' },
    { distance: 796, compassDirection: 'NorthEast', target: 'Victoria bus station, Nottingham' }
];
data.sort(function (a, b) {
    var D = { North: 0, NorthEast: 45, East: 90, /* ... */ };
    return D[a.compassDirection] - D[b.compassDirection] || a.distance - b.distance;
});
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');