首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javascript中的递归四分位排序器

Javascript中的递归四分位排序器
EN

Stack Overflow用户
提问于 2018-10-24 17:53:48
回答 1查看 62关注 0票数 0

我正在用Javascript构建一个四分位数的分类器。Codepen在下面。将表格中的标题拖到表格上方的灰色区域,以查看表格排序。https://codepen.io/carbondesign/pen/MPPRPW?editors=0010

这段代码工作正常,除了两个问题: 1.我写了它的长手写,以便为我自己分解问题2.按第三列排序不起作用。

要查看#2,请将" area“拖入分类框(表格上方的灰色区域),表格将按预期进行排序(俄罗斯是最大的国家)。将" population“拖动到排序区域,表将按预期进行排序(中国是最大、人口最多的国家)。将“人口增长率”拖到分拣区,它几乎是有效的,但并不完全有效。我得到了双精度值,排序顺序应该如下所示,伊拉克是最大、人口最多、增长率最高的国家。

  • 伊拉克2.93
  • 埃塞俄比亚2.89
  • 坦桑尼亚2.79
  • 安哥拉2.77
  • 喀麦隆H114也门2.47
  • 尼日利亚2.45

刚果2.45

  • Mozambique 2.45
  • Afganistan 2.32H223肯尼亚1.93
  • 阿尔及利亚1.84
  • 埃及1.79
  • 苏丹1.72
  • 印度1.22
  • Pakistan

/code>

  • 沙特阿拉伯1.46
  • Venezuela 1.39
  • 南非1.33
  • 土耳其1.26
  • 伊朗1.2
  • 墨西哥1.18
  • Australia 1.07
  • Columbia 1.04
  • 缅甸1.01
  • Morrocco 1
  • ...

有问题的代码从第154行开始(同样,我特意用手写了这段代码):

代码语言:javascript
复制
    let thirdBuckets = [[],[],[],[]]
    secondBuckets.forEach( (secondbucket) => {
        secondbucket.forEach((currentVal) => {
            if(currentVal[sorters[i]] !== null){
                if(currentVal[sorters[i]] > columnSummary[sorters[i]].min && currentVal[sorters[i]] <= columnSummary[sorters[i]].first){
                    thirdBuckets[0].push(currentVal);
                }
                if(currentVal[sorters[i]] > columnSummary[sorters[i]].first && currentVal[sorters[i]] <= columnSummary[sorters[i]].mean){
                    thirdBuckets[1].push(currentVal);
                }
                if(currentVal[sorters[i]] > columnSummary[sorters[i]].mean && currentVal[sorters[i]] <= columnSummary[sorters[i]].third){
                    thirdBuckets[2].push(currentVal);
                }
                if(currentVal[sorters[i]] > columnSummary[sorters[i]].third && currentVal[sorters[i]] <= columnSummary[sorters[i]].max){
                    thirdBuckets[3].push(currentVal);
                }
            }else{
                nullBucket.push(currentVal);
            }
        });
        secondbucket.length = 0;
        thirdBuckets.forEach((thirdbucket) => {
            thirdbucket.forEach((currentVal) => {
                secondbucket.push(currentVal)
            })
        });

    })
    console.log(thirdBuckets);
    results.length = 0;
    secondBuckets.forEach((secondbucket) => {
        // regularSort(secondbucket, sorters[i])
        secondbucket.forEach((currentVal) => {
                results.push(currentVal)
        })
    })
}

感谢所有的建议。

EN

回答 1

Stack Overflow用户

发布于 2018-10-25 03:58:34

给定一个排序方法数组:

代码语言:javascript
复制
[ (a, b) -> n ]

您可以通过迭代这些方法并应用它们,直到第一个方法返回-11,从而创建组合排序方法。您可以使用递归来完成此操作,但在简单的循环中会更容易:

代码语言:javascript
复制
// Using recursion
const chainSortRec = ([s = Done, ...sorters]) => 
  (a, b) => s === Done 
    ? 0 
    : s(a, b) || chainSortRec(sorters)(a, b);

// Using a regular loop
const chainSort = (sorters) => (a, b) => {
  for (let i = 0; i < sorters.length; i += 1) {
   const res = sorters[i](a, b);
   if (res) return res;
  }    
  return 0;
};

下面是一个基于多个排序器对一组数组进行排序的示例:

代码语言:javascript
复制
const numSort = (a, b) => a > b ? -1 : a < b ? 1 : 0;

const sortBy0 = ([a  ], [b  ]) => numSort(a, b);
const sortBy1 = ([,a ], [,b ]) => numSort(a, b);
const sortBy2 = ([,,a], [,,b]) => numSort(a, b);

const Done = Symbol();

// Applies the first sort method, if any.
// If it returns 0, it recurses to the next.
// When out of sort methods, it returns 0.
const chainSortRec = ([s = Done, ...sorters]) => 
  (a, b) => s === Done 
    ? 0 
    : s(a, b) || chainSortRec(sorters)(a, b);

const data = [
  [2, 0, 0],
  [1, 0, 0],
  [1, 1, 1],
  [1, 1, 0],
  [3, 0, 0],
];

console.log(
  data
    .sort(chainSortRec([sortBy0, sortBy1, sortBy2]))
    .map(xs => `[ ${xs} ]`)
    .join("\n")
);

这可能只是部分地回答了你的问题,但我花了很长时间来检查你的所有代码行以及与UI代码的混合……

无论如何,这里有一个完整的运行控制台示例,其中包含许多注释,它们给出了您所需的结果:

代码语言:javascript
复制
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释 
* const data = [{"name":"Afghanistan","area":652230,"population":32564342,"populationGrowthRate":2.32},{"name":"Akrotiri","area":123,"population":null,"populationGrowthRate":null},{"name":"Albania","area":28748,"population":3029278,"populationGrowthRate":0.3},{"name":"Algeria","area":2381741,"population":39542166,"populationGrowthRate":1.84},{"name":"American Samoa","area":199,"population":54343,"populationGrowthRate":-0.3},{"name":"Andorra","area":468,"population":85580,"populationGrowthRate":0.12},{"name":"Angola","area":1246700,"population":19625353,"populationGrowthRate":2.77},{"name":"Anguilla","area":91,"population":16418,"populationGrowthRate":2.03},{"name":"Antarctica","area":null,"population":null,"populationGrowthRate":null},{"name":"Antigua and Barbuda","area":443,"population":92436,"populationGrowthRate":1.24},{"name":"Argentina","area":2780400,"population":43431886,"populationGrowthRate":0.93},{"name":"Armenia","area":29743,"population":3056382,"populationGrowthRate":-0.15},{"name":"Aruba","area":180,"population":112162,"populationGrowthRate":1.33},{"name":"Ashmore and Cartier Islands","area":5,"population":null,"populationGrowthRate":null},{"name":"Australia","area":7741220,"population":22751014,"populationGrowthRate":1.07},{"name":"Austria","area":83871,"population":8665550,"populationGrowthRate":0.55},{"name":"Azerbaijan","area":86600,"population":9780780,"populationGrowthRate":0.96},{"name":"Bahamas The","area":13880,"population":324597,"populationGrowthRate":0.84},{"name":"Bahrain","area":760,"population":1346613,"populationGrowthRate":2.41},{"name":"Bangladesh","area":143998,"population":168957745,"populationGrowthRate":1.6},{"name":"Barbados","area":430,"population":290604,"populationGrowthRate":0.31},{"name":"Belarus","area":207600,"population":9589689,"populationGrowthRate":-0.2},{"name":"Belgium","area":30528,"population":11323973,"populationGrowthRate":0.76},{"name":"Belize","area":22966,"population":347369,"populationGrowthRate":1.87},{"name":"Benin","area":112622,"population":10448647,"populationGrowthRate":2.78},{"name":"Bermuda","area":54,"population":70196,"populationGrowthRate":0.5},{"name":"Bhutan","area":38394,"population":741919,"populationGrowthRate":1.11},{"name":"Bolivia","area":1098581,"population":10800882,"populationGrowthRate":1.56},{"name":"Bosnia and Herzegovina","area":51197,"population":3867055,"populationGrowthRate":-0.13},{"name":"Botswana","area":581730,"population":2182719,"populationGrowthRate":1.21},{"name":"Bouvet Island","area":49,"population":null,"populationGrowthRate":null},{"name":"Brazil","area":8514877,"population":204259812,"populationGrowthRate":0.77},{"name":"British Indian Ocean Territory","area":54400,"population":null,"populationGrowthRate":null},{"name":"British Virgin Islands","area":151,"population":33454,"populationGrowthRate":2.32},{"name":"Brunei","area":5765,"population":429646,"populationGrowthRate":1.62},{"name":"Bulgaria","area":110879,"population":7186893,"populationGrowthRate":-0.58},{"name":"Burkina Faso","area":274200,"population":18931686,"populationGrowthRate":3.03},{"name":"Burma","area":676578,"population":56320206,"populationGrowthRate":1.01},{"name":"Burundi","area":27830,"population":10742276,"populationGrowthRate":3.27},{"name":"Cabo Verde","area":4033,"population":545993,"populationGrowthRate":1.36},{"name":"Cambodia","area":181035,"population":15708756,"populationGrowthRate":1.58},{"name":"Cameroon","area":475440,"population":23739218,"populationGrowthRate":2.59},{"name":"Canada","area":9984670,"population":35099836,"populationGrowthRate":0.75},{"name":"Cayman Islands","area":264,"population":56092,"populationGrowthRate":2.1},{"name":"Central African Republic","area":622984,"population":5391539,"populationGrowthRate":2.13},{"name":"Chad","area":1284000,"population":11631456,"populationGrowthRate":1.89},{"name":"Chile","area":756102,"population":17508260,"populationGrowthRate":0.82},{"name":"China","area":9596960,"population":1367485388,"populationGrowthRate":0.45},{"name":"Christmas Island","area":135,"population":1530,"populationGrowthRate":1.11},{"name":"Clipperton Island","area":6,"population":null,"populationGrowthRate":null},{"name":"Cocos (Keeling) Islands","area":14,"population":596,"populationGrowthRate":0},{"name":"Colombia","area":1138910,"population":46736728,"populationGrowthRate":1.04},{"name":"Comoros","area":2235,"population":780971,"populationGrowthRate":1.77},{"name":"Congo Democratic Republic of the","area":2344858,"population":79375136,"populationGrowthRate":2.45},{"name":"Congo Republic of the","area":342000,"population":4755097,"populationGrowthRate":2},{"name":"Cook Islands","area":236,"population":9838,"populationGrowthRate":-2.95},{"name":"Coral Sea Islands","area":3,"population":null,"populationGrowthRate":null},{"name":"Costa Rica","area":51100,"population":4814144,"populationGrowthRate":1.22},{"name":"Cote d'Ivoire","area":322463,"population":23295302,"populationGrowthRate":1.91},{"name":"Croatia","area":56594,"population":4464844,"populationGrowthRate":-0.13},{"name":"Cuba","area":110860,"population":11031433,"populationGrowthRate":-0.15},{"name":"Curacao","area":444,"population":146836,"populationGrowthRate":null},{"name":"Cyprus","area":9251,"population":1189197,"populationGrowthRate":1.43},{"name":"Czech Republic","area":78867,"population":10644842,"populationGrowthRate":0.16},{"name":"Ecuador","area":283561,"population":15868396,"populationGrowthRate":1.35},{"name":"Egypt","area":1001450,"population":88487396,"populationGrowthRate":1.79},{"name":"El Salvador","area":21041,"population":6141350,"populationGrowthRate":0.25},{"name":"Equatorial Guinea","area":28051,"population":740743,"populationGrowthRate":2.51},{"name":"Eritrea","area":117600,"population":6527689,"populationGrowthRate":2.25},{"name":"Estonia","area":45228,"population":1265420,"populationGrowthRate":-0.55},{"name":"Ethiopia","area":1104300,"population":99465819,"populationGrowthRate":2.89},{"name":"European Union","area":null,"population":513949445,"populationGrowthRate":null},{"name":"Falkland Islands (Islas Malvinas)","area":12173,"population":3361,"populationGrowthRate":0.01},{"name":"Faroe Islands","area":1393,"population":50196,"populationGrowthRate":0.51},{"name":"Fiji","area":18274,"population":909389,"populationGrowthRate":0.67},{"name":"Finland","area":338145,"population":5476922,"populationGrowthRate":0.4},{"name":"France","area":643801,"population":66553766,"populationGrowthRate":0.43},{"name":"French Polynesia","area":4167,"population":282703,"populationGrowthRate":0.94},{"name":"French Southern and Antarctic Lands","area":55,"population":null,"populationGrowthRate":null},{"name":"Gabon","area":267667,"population":1705336,"populationGrowthRate":1.93},{"name":"Gambia The","area":11295,"population":1967709,"populationGrowthRate":2.16},{"name":"Gaza Strip","area":360,"population":1869055,"populationGrowthRate":2.81},{"name":"Georgia","area":69700,"population":4931226,"populationGrowthRate":-0.08},{"name":"Germany","area":357022,"population":80854408,"populationGrowthRate":-0.17},{"name":"Ghana","area":238533,"population":26327649,"populationGrowthRate":2.18},{"name":"Gibraltar","area":7,"population":29258,"populationGrowthRate":0.24},{"name":"Greece","area":131957,"population":10775643,"populationGrowthRate":-0.01},{"name":"Greenland","area":2166086,"population":57733,"populationGrowthRate":0},{"name":"Grenada","area":344,"population":110694,"populationGrowthRate":0.48},{"name":"Guam","area":544,"population":161785,"populationGrowthRate":0.54},{"name":"Guatemala","area":108889,"population":14918999,"populationGrowthRate":1.81},{"name":"Guernsey","area":78,"population":66080,"populationGrowthRate":0.34},{"name":"Guinea","area":245857,"population":11780162,"populationGrowthRate":2.63},{"name":"Guinea-Bissau","area":36125,"population":1726170,"populationGrowthRate":1.91},{"name":"Guyana","area":214969,"population":735222,"populationGrowthRate":0.02},{"name":"Haiti","area":27750,"population":10110019,"populationGrowthRate":1.17},{"name":"Heard Island and McDonald Islands","area":412,"population":null,"populationGrowthRate":null},{"name":"Holy See (Vatican City)","area":0,"population":842,"populationGrowthRate":0},{"name":"Honduras","area":112090,"population":8746673,"populationGrowthRate":1.68},{"name":"Hong Kong","area":1108,"population":7141106,"populationGrowthRate":0.38},{"name":"Howland Island","area":2,"population":null,"populationGrowthRate":null},{"name":"Hungary","area":93028,"population":9897541,"populationGrowthRate":-0.22},{"name":"Iceland","area":103000,"population":331918,"populationGrowthRate":1.21},{"name":"India","area":3287263,"population":1251695584,"populationGrowthRate":1.22},{"name":"Indonesia","area":1904569,"population":255993674,"populationGrowthRate":0.92},{"name":"Iran","area":1648195,"population":81824270,"populationGrowthRate":1.2},{"name":"Iraq","area":438317,"population":37056169,"populationGrowthRate":2.93},{"name":"Ireland","area":70273,"population":4892305,"populationGrowthRate":1.25},{"name":"Isle of Man","area":572,"population":87545,"populationGrowthRate":0.76},{"name":"Israel","area":20770,"population":8049314,"populationGrowthRate":1.56},{"name":"Italy","area":301340,"population":61855120,"populationGrowthRate":0.27},{"name":"Jamaica","area":10991,"population":2950210,"populationGrowthRate":0.68},{"name":"Jan Mayen","area":377,"population":null,"populationGrowthRate":null},{"name":"Japan","area":377915,"population":126919659,"populationGrowthRate":-0.16},{"name":"Jarvis Island","area":5,"population":null,"populationGrowthRate":null},{"name":"Jersey","area":116,"population":97294,"populationGrowthRate":0.8},{"name":"Johnston Atoll","area":3,"population":null,"populationGrowthRate":null},{"name":"Jordan","area":89342,"population":8117564,"populationGrowthRate":0.83},{"name":"Kazakhstan","area":2724900,"population":18157122,"populationGrowthRate":1.14},{"name":"Kenya","area":580367,"population":45925301,"populationGrowthRate":1.93},{"name":"Kingman Reef","area":1,"population":null,"populationGrowthRate":null},{"name":"Kiribati","area":811,"population":105711,"populationGrowthRate":1.15},{"name":"Korea North","area":120538,"population":24983205,"populationGrowthRate":0.53},{"name":"Korea South","area":99720,"population":49115196,"populationGrowthRate":0.14},{"name":"Kosovo","area":10887,"population":1870981,"populationGrowthRate":null},{"name":"Kuwait","area":17818,"population":2788534,"populationGrowthRate":1.62},{"name":"Kyrgyzstan","area":199951,"population":5664939,"populationGrowthRate":1.11},{"name":"Laos","area":236800,"population":6911544,"populationGrowthRate":1.55},{"name":"Latvia","area":64589,"population":1986705,"populationGrowthRate":-1.06},{"name":"Lebanon","area":10400,"population":6184701,"populationGrowthRate":0.86},{"name":"Lesotho","area":30355,"population":1947701,"populationGrowthRate":0.32},{"name":"Liberia","area":111369,"population":4195666,"populationGrowthRate":2.47},{"name":"Libya","area":1759540,"population":6411776,"populationGrowthRate":2.23},{"name":"Liechtenstein","area":160,"population":37624,"populationGrowthRate":0.84},{"name":"Lithuania","area":65300,"population":2884433,"populationGrowthRate":-1.04},{"name":"Luxembourg","area":2586,"population":570252,"populationGrowthRate":2.13},{"name":"Macau","area":28,"population":592731,"populationGrowthRate":0.8},{"name":"Macedonia","area":25713,"population":2096015,"populationGrowthRate":0.2},{"name":"Madagascar","area":587041,"population":23812681,"populationGrowthRate":2.58},{"name":"Malawi","area":118484,"population":17964697,"populationGrowthRate":3.31},{"name":"Malaysia","area":329847,"population":30513848,"populationGrowthRate":1.44},{"name":"Maldives","area":298,"population":393253,"populationGrowthRate":-0.08},{"name":"Mali","area":1240192,"population":16955536,"populationGrowthRate":2.98},{"name":"Malta","area":316,"population":413965,"populationGrowthRate":0.31},{"name":"Marshall Islands","area":181,"population":72191,"populationGrowthRate":1.66},{"name":"Mauritania","area":1030700,"population":3596702,"populationGrowthRate":2.23},{"name":"Mauritius","area":2040,"population":1339827,"populationGrowthRate":0.64},{"name":"Mexico","area":1964375,"population":121736809,"populationGrowthRate":1.18},{"name":"Micronesia Federated States of","area":702,"population":105216,"populationGrowthRate":-0.46},{"name":"Midway Islands","area":6,"population":null,"populationGrowthRate":null},{"name":"Moldova","area":33851,"population":3546847,"populationGrowthRate":-1.02},{"name":"Monaco","area":2,"population":30535,"populationGrowthRate":0.12},{"name":"Mongolia","area":1564116,"population":2992908,"populationGrowthRate":1.31},{"name":"Montenegro","area":13812,"population":647073,"populationGrowthRate":-0.42},{"name":"Montserrat","area":102,"population":5241,"populationGrowthRate":0.5},{"name":"Morocco","area":446550,"population":33322699,"populationGrowthRate":1},{"name":"Mozambique","area":799380,"population":25303113,"populationGrowthRate":2.45},{"name":"Namibia","area":824292,"population":2212307,"populationGrowthRate":0.59},{"name":"Nauru","area":21,"population":9540,"populationGrowthRate":0.55},{"name":"Navassa Island","area":5,"population":null,"populationGrowthRate":null},{"name":"Nepal","area":147181,"population":31551305,"populationGrowthRate":1.79},{"name":"Netherlands","area":41543,"population":16947904,"populationGrowthRate":0.41},{"name":"New Caledonia","area":18575,"population":271615,"populationGrowthRate":1.38},{"name":"New Zealand","area":267710,"population":4438393,"populationGrowthRate":0.82},{"name":"Nicaragua","area":130370,"population":5907881,"populationGrowthRate":1},{"name":"Niger","area":1267000,"population":18045729,"populationGrowthRate":3.25},{"name":"Nigeria","area":923768,"population":181562056,"populationGrowthRate":2.45},{"name":"Niue","area":260,"population":1190,"populationGrowthRate":-0.03},{"name":"Norfolk Island","area":36,"population":2210,"populationGrowthRate":0.01},{"name":"Northern Mariana Islands","area":464,"population":52344,"populationGrowthRate":2.18},{"name":"Norway","area":323802,"population":5207689,"populationGrowthRate":1.13},{"name":"Oman","area":309500,"population":3286936,"populationGrowthRate":2.06},{"name":"Pakistan","area":796095,"population":199085847,"populationGrowthRate":1.46},{"name":"Palau","area":459,"population":21265,"populationGrowthRate":0.38},{"name":"Palmyra Atoll","area":12,"population":null,"populationGrowthRate":null},{"name":"Panama","area":75420,"population":3657024,"populationGrowthRate":1.32},{"name":"Papua New Guinea","area":462840,"population":6672429,"populationGrowthRate":1.78},{"name":"Paracel Islands","area":null,"population":null,"populationGrowthRate":null},{"name":"Paraguay","area":406752,"population":6783272,"populationGrowthRate":1.16},{"name":"Peru","area":1285216,"population":30444999,"populationGrowthRate":0.97},{"name":"Philippines","area":300000,"population":100998376,"populationGrowthRate":1.61},{"name":"Pitcairn Islands","area":47,"population":48,"populationGrowthRate":0},{"name":"Poland","area":312685,"population":38562189,"populationGrowthRate":-0.09},{"name":"Portugal","area":92090,"population":10825309,"populationGrowthRate":0.09},{"name":"Puerto Rico","area":13790,"population":3598357,"populationGrowthRate":-0.6},{"name":"Qatar","area":11586,"population":2194817,"populationGrowthRate":3.07},{"name":"Romania","area":238391,"population":21666350,"populationGrowthRate":-0.3},{"name":"Russia","area":17098242,"population":142423773,"populationGrowthRate":-0.04},{"name":"Rwanda","area":26338,"population":12661733,"populationGrowthRate":2.56},{"name":"Saint Barthelemy","area":null,"population":7237,"populationGrowthRate":null},{"name":"Saint Helena Ascension and Tristan da Cunha","area":308,"population":7795,"populationGrowthRate":0.24},{"name":"Saint Kitts and Nevis","area":261,"population":51936,"populationGrowthRate":0.76},{"name":"Saint Lucia","area":616,"population":163922,"populationGrowthRate":0.34},{"name":"Saint Martin","area":54,"population":31754,"populationGrowthRate":null},{"name":"Saint Pierre and Miquelon","area":242,"population":5657,"populationGrowthRate":-1.08},{"name":"Saint Vincent and the Grenadines","area":389,"population":102627,"populationGrowthRate":-0.28},{"name":"Samoa","area":2831,"population":197773,"populationGrowthRate":0.58},{"name":"San Marino","area":61,"population":33020,"populationGrowthRate":0.82},{"name":"Sao Tome and Principe","area":964,"population":194006,"populationGrowthRate":1.84},{"name":"Saudi Arabia","area":2149690,"population":27752316,"populationGrowthRate":1.46},{"name":"Senegal","area":196722,"population":13975834,"populationGrowthRate":2.45},{"name":"Serbia","area":77474,"population":7176794,"populationGrowthRate":-0.46},{"name":"Seychelles","area":455,"population":92430,"populationGrowthRate":0.83},{"name":"Sierra Leone","area":71740,"population":5879098,"populationGrowthRate":2.35},{"name":"Singapore","area":697,"population":5674472,"populationGrowthRate":1.89},{"name":"Sint Maarten","area":34,"population":39689,"populationGrowthRate":1.51},{"name":"Slovakia","area":49035,"population":5445027,"populationGrowthRate":0.02},{"name":"Slovenia","area":20273,"population":1983412,"populationGrowthRate":-0.26},{"name":"Solomon Islands","area":28896,"population":622469,"populationGrowthRate":2.02},{"name":"Somalia","area":637657,"population":10616380,"populationGrowthRate":1.83},{"name":"South Africa","area":1219090,"population":53675563,"populationGrowthRate":1.33},{"name":"South Georgia and South Sandwich Islands","area":3903,"population":null,"populationGrowthRate":null},{"name":"South Sudan","area":644329,"population":12042910,"populationGrowthRate":4.02},{"name":"Spain","area":505370,"population":48146134,"populationGrowthRate":0.89},{"name":"Spratly Islands","area":5,"population":null,"populationGrowthRate":null},{"name":"Sri Lanka","area":65610,"population":22053488,"populationGrowthRate":0.84},{"name":"Sudan","area":1861484,"population":36108853,"populationGrowthRate":1.72},{"name":"Suriname","area":163820,"population":579633,"populationGrowthRate":1.08},{"name":"Svalbard","area":62045,"population":1872,"populationGrowthRate":-0.03},{"name":"Swaziland","area":17364,"population":1435613,"populationGrowthRate":1.11},{"name":"Sweden","area":450295,"population":9801616,"populationGrowthRate":0.8},{"name":"Switzerland","area":41277,"population":8121830,"populationGrowthRate":0.71},{"name":"Syria","area":185180,"population":17064854,"populationGrowthRate":-0.16},{"name":"Taiwan","area":35980,"population":23415126,"populationGrowthRate":0.23},{"name":"Tajikistan","area":143100,"population":8191958,"populationGrowthRate":1.71},{"name":"Tanzania","area":947300,"population":51045882,"populationGrowthRate":2.79},{"name":"Thailand","area":513120,"population":67976405,"populationGrowthRate":0.34},{"name":"Timor-Leste","area":14874,"population":1231116,"populationGrowthRate":2.42},{"name":"Togo","area":56785,"population":7552318,"populationGrowthRate":2.69},{"name":"Trinidad and Tobago","area":5128,"population":1222363,"populationGrowthRate":-0.13},{"name":"Tunisia","area":163610,"population":11037225,"populationGrowthRate":0.89},{"name":"Turkey","area":783562,"population":79414269,"populationGrowthRate":1.26},{"name":"Turkmenistan","area":488100,"population":5231422,"populationGrowthRate":1.14},{"name":"Turks and Caicos Islands","area":948,"population":50280,"populationGrowthRate":2.3},{"name":"Tuvalu","area":26,"population":10869,"populationGrowthRate":0.82},{"name":"Uganda","area":241038,"population":37101745,"populationGrowthRate":3.24},{"name":"Ukraine","area":603550,"population":44429471,"populationGrowthRate":-0.6},{"name":"United Arab Emirates","area":83600,"population":5779760,"populationGrowthRate":2.58},{"name":"United Kingdom","area":243610,"population":64088222,"populationGrowthRate":0.54},{"name":"United States","area":9826675,"population":321368864,"populationGrowthRate":0.78},{"name":"United States Pacific Island Wildlife Refuges","area":22,"population":null,"populationGrowthRate":null},{"name":"Uruguay","area":176215,"population":3341893,"populationGrowthRate":0.27},{"name":"Uzbekistan","area":447400,"population":29199942,"populationGrowthRate":0.93},{"name":"Vanuatu","area":12189,"population":272264,"populationGrowthRate":1.95},{"name":"Venezuela","area":912050,"population":29275460,"populationGrowthRate":1.39},{"name":"Vietnam","area":331210,"population":94348835,"populationGrowthRate":0.97},{"name":"Virgin Islands","area":1910,"population":103574,"populationGrowthRate":-0.59},{"name":"Wake Island","area":7,"population":null,"populationGrowthRate":null},{"name":"Wallis and Futuna","area":142,"population":15613,"populationGrowthRate":0.33},{"name":"West Bank","area":5860,"population":2785366,"populationGrowthRate":1.95},{"name":"Western Sahara","area":266000,"population":570866,"populationGrowthRate":2.82},{"name":"Yemen","area":527968,"population":26737317,"populationGrowthRate":2.47},{"name":"Zambia","area":752618,"population":15066266,"populationGrowthRate":2.88},{"name":"Zimbabwe","area":390757,"population":14229541,"populationGrowthRate":2.21}];
*/


// Logic helpers

// Returns the value at a point in a sorted array. E.g. p = 0.5 -> median
const valueAtPoint = (xs, p) => xs[Math.floor(xs.length * p)];

// Gets the index of an element's quarter in an array
const getQuarter = (xs, x) =>
  x === null                  ? null :
  x <= valueAtPoint(xs, 0.75) ? 0 :
  x <= valueAtPoint(xs, 0.50) ? 1 :
  x <= valueAtPoint(xs, 0.25) ? 2 :
                                3 ;

// Sort numbers largest first, null last
const numericNullLastSorter = (a, b) => 
  a === null ?  1 :
  b === null ? -1 :
  a < b      ?  1 :
  a > b      ? -1 :
                0 ;

// Decorates a sort function to first unwrap property values
const propSorter = (k, f) => (a, b) => f(a[k], b[k]);

// A recursive sort-chainer that keeps on recursing
// until it's either out of sorters, or a sorter has returned
// -1 or 1
const chainSortRec = ([s, ...sorters]) => (a, b) => 
s === undefined ?
  0 :
  s(a, b) || chainSortRec(sorters)(a, b);

// The same sort-chain but implemented as a loop
const chainSort = (sorters) => (a, b) => {
  for (let i = 0; i < sorters.length; i += 1) {
   const res = sorters[i](a, b);
   if (res) return res;
  }    
  return 0;
};

// The main app logic
// props is an array of strings (keys) we want to sort by, in order
// xs is an array of objects that contain those keys
const sortByProps = (props, xs) => {
const og = Symbol();
const quarterProps = props.slice(0, -1)
const numericProp = props[props.length - 1];

// For every property that sortst by quarter,
// we'll need to sort all items to be able to 
// determine the quarter indexes.
const sorts = Object.assign(
  {},
  ...quarterProps.map(k => ({
    [k]: xs
          .map(x => x[k])
          .filter(x => x !== null)
          .sort(numericNullLastSorter)
  }))
);

// We need a place to link the original entries ot the
// values that determine their sort order
const qIndex = xs.map(x => Object.assign(
  // Store a reference to the original item
  { [og]: x },
  // Store the numeric value of the last prop
  { [numericProp]: x[numericProp] },
  // Store the quarter index of the other props
  ...quarterProps.map(k => ({
      [k]: getQuarter(sorts[k], x[k])
  }))
));

// This is our array of sort functions
// Each sort function sorts descending based on a single property
const sorters = props.map(k => propSorter(k, numericNullLastSorter));


return qIndex
  // We sort the index based on all sort methods
  .sort(chainSort(sorters))
  // We return the original objects, not the cached sort values
  .map(x => x[og]);
}



// To format our tests:
const topFiveString = props => sortByProps(props, data)
  .slice(0, 5)
  .map(x => x.name)
  .join(", ");

console.log(

`TOP 5s:
  by area: 
    ${topFiveString(["area"])}
  by area & population: 
    ${topFiveString(["area", "population"])}
  by area, population & growth rate: 
    ${topFiveString(["area", "population", "populationGrowthRate"])}`

);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52966025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档