我正在用Javascript构建一个四分位数排序器。 Codepen在下面。将表中的标题拖到表上方的灰色区域以查看表的排序。 https://codepen.io/carbondesign/pen/MPPRPW?editors=0010
此代码有效,但有两个问题: 我写了很长的篇幅,以便自己解决问题。 2.按第三列排序不起作用。
要查看#2,请将“区域”拖动到排序器框中(表格上方的灰色区域),表格将按预期进行排序(俄罗斯是最大的国家)。将“人口”拖到分类器区域,表格将按预期进行排序(中国是最大,人口最多的国家)。将“人口增长率”拖到分拣机区域中,这几乎可行,但效果不佳。我得到双重值,排序顺序应如下,伊拉克是最大,人口最多的国家,增长率最高。
有问题的代码从154行开始(再次,我是故意写出来的):
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)
})
})
}
感谢所有建议。
答案 0 :(得分:1)
给出一系列排序方法:
[ (a, b) -> n ]
您可以通过迭代方法并应用它们直到第一个返回-1
或1
来创建组合排序方法。您可以使用递归来做到这一点,但是在一个简单的循环中会更容易:
// 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;
};
一个基于多个排序器对一组数组进行排序的示例:
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代码的混合使用...
无论如何,这是一个完整的正在运行的控制台示例,其中包含大量注释,可以提供您所需的结果:
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"])}`
);