如何通过嵌套属性对数组进行排序 [英] how to sort array by nested properties
问题描述
let array = [{"id":248439,"name":"Cross Creek Ranch/Creek Cove","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Cross Creek Ranch/Creek Cove","subdivisionId":248439,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248545,"name":"Lakes of Bella Terra/Via Verdone","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Lakes of Bella Terra/Via Verdone","subdivisionId":248545,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248546,"name":"Lakes of Bella Terra/Via Moderna","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:24:24.312","lng":-95.78459389953542,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"248546","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Via Moderna","dateTimeUploaded":"2017-03-13 14:24:24.316","lat":29.68844027643332}},{"id":248547,"name":"Lakes of Bella Terra/Via Privato","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Lakes of Bella Terra/Via Privato","subdivisionId":248547,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248548,"name":"Lakes of Bella Terra/Mirandola","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Lakes of Bella Terra/Mirandola","subdivisionId":248548,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248549,"name":"Lakes of Bella Terra/La Bella Cortile","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:38:22.958","lng":-95.78834879221002,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"248549","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/La Bella Cortile","dateTimeUploaded":"2017-03-13 14:38:22.964","lat":29.69532227612072}},{"id":248838,"name":"Cross Creek Ranch/Pond","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 12:12:20.408","lng":-95.8761960827707,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"248838","surveyStatus":"1","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/Pond","dateTimeUploaded":"2017-03-14 12:12:20.416","lat":29.70182981810505}},{"id":249626,"name":"Cross Creek Ranch/Legacy-Herons Lake","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 13:11:24.276","lng":-95.8625899069904,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249626","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/Legacy-Herons Lake","dateTimeUploaded":"2017-03-14 13:11:24.282","lat":29.70904039221789}},{"id":249727,"name":"Fulshear Run","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 11:49:22.765","lng":-95.8850889467596,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249727","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Fulshear Run","dateTimeUploaded":"2017-03-14 11:49:22.772","lat":29.6824066434332}},{"id":249739,"name":"Lakes of Bella Terra/Cittanova","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 15:56:25.460","lng":-95.78473585666696,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249739","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Cittanova","dateTimeUploaded":"2017-03-13 15:56:25.467","lat":29.69387132677221}},{"id":249883,"name":"Lakes of Bella Terra/Vita Bella","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 15:54:04.856","lng":-95.78164947228113,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249883","surveyStatus":"1","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Vita Bella","dateTimeUploaded":"2017-03-13 15:54:04.864","lat":29.69463965392643}},{"id":249884,"name":"Lakes of Bella Terra/Valencia","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:32:35.471","lng":-95.78839095318297,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249884","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Valencia","dateTimeUploaded":"2017-03-13 14:32:35.477","lat":29.69075137286418}},{"id":249885,"name":"Lakes of Bella Terra/Porte Toscana","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:10:33.875","lng":-95.79300477178376,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249885","surveyStatus":"1","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Porte Toscana","dateTimeUploaded":"2017-03-13 14:10:33.882","lat":29.68849873638683}},{"id":249920,"name":"Cross Creek Ranch/The Falls","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 15:07:57.054","lng":-95.86257892669724,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249920","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/The Falls","dateTimeUploaded":"2017-03-14 15:07:57.060","lat":29.73065241708395}},{"id":249941,"name":"Cross Creek Ranch/Heights","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 13:38:52.380","lng":-95.85420054392503,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249941","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/Heights","dateTimeUploaded":"2017-03-14 13:38:52.385","lat":29.71784273165252}}]
const sortSurveyStatusDate = (option, array) => {
switch (option) {
case 'dateTimeAdded':
array.sort((a, b) => {
a = new Date(a.surveyStatus.dateTimeAdded)
b = new Date(b.surveyStatus.dateTimeAdded)
return a > b ? -1 : a < b ? 1 : 0
})
break
case '-dateTimeAdded':
array.sort((a, b) => {
a = new Date(a.surveyStatus.dateTimeAdded)
b = new Date(b.surveyStatus.dateTimeAdded)
return a < b ? -1 : a > b ? 1 : 0
})
break
}
return array
}
const sortSurveyStatus = (option, array) => {
switch (option) {
case 'complete':
array.sort((a, b) => {
return b.surveyStatus.surveyStatus > a.surveyStatus.surveyStatus
})
break
case 'inProgress':
array.sort((a, b) => {
return a.surveyStatus.surveyStatus > b.surveyStatus.surveyStatus
})
break
case 'notStarted':
array.sort((a) => {
return a.surveyStatus.surveyStatus === '0'
})
break
}
return array
}
const dateDesc = '-dateTimeAdded'
const dateAsc = 'dateTimeAdded'
const status_1 = '1'
const status_2 = '2'
const status_3 = '3'
// array = sortSurveyStatusDate(dateDesc, array)
// array = sortSurveyStatusDate(dateAsc, array)
// array = sortSurveyStatus(status_1, array)
// array = sortSurveyStatus(status_2, array)
// array = sortSurveyStatus(status_3, array)
var html = "<table border='1|1'>";
for (var i = 0; i < array.length; i++) {
html+="<tr>";
html+="<td>"+array[i].surveyStatus.subdivisionName+"</td>";
html+="<td>"+array[i].surveyStatus.dateTimeAdded+"</td>";
html+="<td>"+array[i].surveyStatus.surveyStatus+"</td>";
html+="</tr>";
}
html+="</table>";
document.getElementById("box").innerHTML = html;
<div id= "box"></div>
我有一个需要排序的对象数组.有两个选择框,一个选择框按Date(asc/desc)属性排序,另一个选择按"surveyStatus"属性排序.
I have an array of objects that I need to sort. There is two select boxes, one to sort by a Date(asc/desc) property and the other to sort by a "surveyStatus" property.
日期的可能值为null或dateTime戳.
The date has the possible value of null or a dateTime stamp.
SurveyStatus具有3个可能的值,0,1,2.
SurveyStatus has 3 possible values, 0,1,2.
调查状态"的默认排序顺序为1,2,0
The default sort order for the Survey Status is 1,2,0
推荐答案
您可以在单独的对象中定义比较函数,并在调用sort
时引用您需要的比较函数:
You could define your compare functions in a separate object, and reference the one your need when you call sort
:
这里有一个代码片段可以做到这一点:
Here is a snippet that does that:
const array = [{"id":248439,"name":"Cross Creek Ranch/Creek Cove","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Cross Creek Ranch/Creek Cove","subdivisionId":248439,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248545,"name":"Lakes of Bella Terra/Via Verdone","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Lakes of Bella Terra/Via Verdone","subdivisionId":248545,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248546,"name":"Lakes of Bella Terra/Via Moderna","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:24:24.312","lng":-95.78459389953542,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"248546","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Via Moderna","dateTimeUploaded":"2017-03-13 14:24:24.316","lat":29.68844027643332}},{"id":248547,"name":"Lakes of Bella Terra/Via Privato","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Lakes of Bella Terra/Via Privato","subdivisionId":248547,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248548,"name":"Lakes of Bella Terra/Mirandola","surveyStatus":{"territoryName":"Fulshear","subdivisionName":"Lakes of Bella Terra/Mirandola","subdivisionId":248548,"dateTimeAdded":null,"surveyStatus":"0"}},{"id":248549,"name":"Lakes of Bella Terra/La Bella Cortile","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:38:22.958","lng":-95.78834879221002,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"248549","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/La Bella Cortile","dateTimeUploaded":"2017-03-13 14:38:22.964","lat":29.69532227612072}},{"id":248838,"name":"Cross Creek Ranch/Pond","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 12:12:20.408","lng":-95.8761960827707,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"248838","surveyStatus":"1","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/Pond","dateTimeUploaded":"2017-03-14 12:12:20.416","lat":29.70182981810505}},{"id":249626,"name":"Cross Creek Ranch/Legacy-Herons Lake","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 13:11:24.276","lng":-95.8625899069904,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249626","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/Legacy-Herons Lake","dateTimeUploaded":"2017-03-14 13:11:24.282","lat":29.70904039221789}},{"id":249727,"name":"Fulshear Run","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 11:49:22.765","lng":-95.8850889467596,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249727","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Fulshear Run","dateTimeUploaded":"2017-03-14 11:49:22.772","lat":29.6824066434332}},{"id":249739,"name":"Lakes of Bella Terra/Cittanova","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 15:56:25.460","lng":-95.78473585666696,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249739","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Cittanova","dateTimeUploaded":"2017-03-13 15:56:25.467","lat":29.69387132677221}},{"id":249883,"name":"Lakes of Bella Terra/Vita Bella","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 15:54:04.856","lng":-95.78164947228113,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249883","surveyStatus":"1","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Vita Bella","dateTimeUploaded":"2017-03-13 15:54:04.864","lat":29.69463965392643}},{"id":249884,"name":"Lakes of Bella Terra/Valencia","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:32:35.471","lng":-95.78839095318297,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249884","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Valencia","dateTimeUploaded":"2017-03-13 14:32:35.477","lat":29.69075137286418}},{"id":249885,"name":"Lakes of Bella Terra/Porte Toscana","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-13 14:10:33.875","lng":-95.79300477178376,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249885","surveyStatus":"1","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Lakes of Bella Terra/Porte Toscana","dateTimeUploaded":"2017-03-13 14:10:33.882","lat":29.68849873638683}},{"id":249920,"name":"Cross Creek Ranch/The Falls","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 15:07:57.054","lng":-95.86257892669724,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249920","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/The Falls","dateTimeUploaded":"2017-03-14 15:07:57.060","lat":29.73065241708395}},{"id":249941,"name":"Cross Creek Ranch/Heights","surveyStatus":{"territoryName":"Fulshear","dateTimeAdded":"2017-03-14 13:38:52.380","lng":-95.85420054392503,"userId":"6e77831f-9be5-41a4-8135-d961a94ef917","subdivisionId":"249941","surveyStatus":"2","territoryId":"4921","userName":"Michelle Artis","marketId":"13","subdivisionName":"Cross Creek Ranch/Heights","dateTimeUploaded":"2017-03-14 13:38:52.385","lat":29.71784273165252}}];
const populate = (array) => {
const rows = [];
for (let i = 0; i < array.length; i++) {
rows.push("<tr>",
"<td>",array[i].surveyStatus.subdivisionName,"</td>",
"<td>",array[i].surveyStatus.dateTimeAdded,"</td>",
"<td>",array[i].surveyStatus.surveyStatus,"</td>",
"</tr>");
}
document.getElementById("box").innerHTML = "<table border='1|1'>" +
rows.join("") + "</table>";
}
const compare = {
dateTimeAdded: (a, b) => // keep null at the end
(Date.parse(a.surveyStatus.dateTimeAdded) || Infinity) -
(Date.parse(b.surveyStatus.dateTimeAdded) || Infinity),
"-dateTimeAdded": (a, b) => // keep null at the end
(Date.parse(b.surveyStatus.dateTimeAdded) || 0) -
(Date.parse(a.surveyStatus.dateTimeAdded) || 0),
inProgress: (a, b) => b.surveyStatus.surveyStatus - a.surveyStatus.surveyStatus,
notStarted: (a, b) => a.surveyStatus.surveyStatus - b.surveyStatus.surveyStatus,
complete: (a, b) => // Give precedence to status 1
(b.surveyStatus.surveyStatus + 1) % 3 - (a.surveyStatus.surveyStatus + 1) % 3,
};
const sortTable = (option, array) => populate(array.sort(compare[option]));
const sort = document.getElementById('sort');
sort.addEventListener('change', e => sortTable(sort.value, array) );
sortTable(sort.value, array); // sort table at page load
<select id="sort">
<option value="complete">Sort Completed First</option>
<option value="inProgress">Sort In-Progress First</option>
<option value="notStarted">Sort Not-Started First</option>
<option value="dateTimeAdded">Sort Added Asc</option>
<option value="-dateTimeAdded">Sort Added Desc</option>
</select>
<div id= "box"></div>
请注意,sort
在大多数浏览器中提供稳定的排序,这意味着,如果您首先按日期排序,然后再按状态排序,则记录仍将在同一状态组中按日期排序.
Note that sort
provides a stable sort in most browsers, meaning that if you first sort by date, and then by a status, the records will still be sorted by date within the same status group.
这篇关于如何通过嵌套属性对数组进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!