Я столкнулся с проблемой сортировки массива объектов с изменением приоритета значений, в основном я хочу сортировать массив людей по их возрасту, а затем по фамилии - или просто по фамилии, имени. Я думаю, что это самое простое решение по сравнению с другими ответами.
it 'используется при вызове sortPeoples ([' array ',' of ',' properties '], reverse = false)
///////////////////////example array of peoples ///////////////////////
var peoples = [
{name: "Zach", surname: "Emergency", age: 1},
{name: "Nancy", surname: "Nurse", age: 1},
{name: "Ethel", surname: "Emergency", age: 1},
{name: "Nina", surname: "Nurse", age: 42},
{name: "Anthony", surname: "Emergency", age: 42},
{name: "Nina", surname: "Nurse", age: 32},
{name: "Ed", surname: "Emergency", age: 28},
{name: "Peter", surname: "Physician", age: 58},
{name: "Al", surname: "Emergency", age: 58},
{name: "Ruth", surname: "Registration", age: 62},
{name: "Ed", surname: "Emergency", age: 38},
{name: "Tammy", surname: "Triage", age: 29},
{name: "Alan", surname: "Emergency", age: 60},
{name: "Nina", surname: "Nurse", age: 58}
];
//////////////////////// Sorting function /////////////////////
function sortPeoples(propertyArr, reverse) {
function compare(a,b) {
var i=0;
while (propertyArr[i]) {
if (a[propertyArr[i]] < b[propertyArr[i]]) return -1;
if (a[propertyArr[i]] > b[propertyArr[i]]) return 1;
i++;
}
return 0;
}
peoples.sort(compare);
if (reverse){
peoples.reverse();
}
};
////////////////end of sorting method///////////////
function printPeoples(){
$('#output').html('');
peoples.forEach( function(person){
$('#output').append(person.surname+" "+person.name+" "+person.age+"<br>");
} )
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<html>
<body>
<button onclick="sortPeoples(['surname']); printPeoples()">sort by ONLY by surname ASC results in mess with same name cases</button><br>
<button onclick="sortPeoples(['surname', 'name'], true); printPeoples()">sort by surname then name DESC</button><br>
<button onclick="sortPeoples(['age']); printPeoples()">sort by AGE ASC. Same issue as in first case</button><br>
<button onclick="sortPeoples(['age', 'surname']); printPeoples()">sort by AGE and Surname ASC. Adding second field fixed it.</button><br>
<div id="output"></div>
</body>
</html>
Вот способ сделать это с помощью рекурсивной асинхронной функции, ожидающей завершения выборки дочерних элементов, прежде чем возвращать обещание.
Таким образом, мы можем вызвать doSomething
, когда все будет сделано.
const tree = {
url: 'http://www.json-generator.com/api/json/get/cevhxOsZnS',
children: [{
url: 'http://www.json-generator.com/api/json/get/cguaPsRxAi'
}, {
url: 'http://www.json-generator.com/api/json/get/cguaPsRxAi',
children: [{
url: 'http://www.json-generator.com/api/json/get/cfDZdmxnDm'
}]
}]
};
function doSomething() {
console.log("doing something");
}
async function fetchIt(element) {
if (element.children) {
await Promise.all(element.children.map(fetchIt));
}
return new Promise((resolve) => {
console.log("fetching " + element.url);
fetch(element.url).then(res => {
console.log("done");
resolve();
});
});
}
fetchIt(tree).then(doSomething);
Просто сначала подождите, пока элементы слоя будут извлечены, а затем рекурсивно продолжите работу с дочерними элементами и ждите, что:
async function fetchChildren(layer) {
await Promise.all(layer.map(fetch));
await Promise.all(layer.map(el => fetchChildren(el.children)));
}
( fetch (el) должна быть многообещающей функцией )