Я хочу сортировать массив по родительским отношениям. В принципе, я хочу, чтобы все записи были в порядке, где родительский индекс всегда должен быть выше дочернего индекса. Родитель может быть связан только один раз, поэтому единственная проблема заключается в том, что ребенок может быть родителем. Источник данных будет выглядеть так:
[{
id: 1,
parentId: null
}, {
id: 2,
parentId: 4
}, {
id: 3,
parentId: null
}, {
id: 4,
parentId: 3
}, {
id: 5,
parentId: 2
}]
Один из методов, которые я пытался, заключался в том, чтобы проверить, находится ли родитель записи ниже текущего индекса и соответственно подняться вверх, но это бесконечно циклично и становится очень неэффективным.
function hasParentAbove(collection, rec) {
if (rec.parentId === null) {
return true;
};
let parentIndex = collection.map(s => s.id).indexOf(rec.parentId);
let recIndex = collection.map(s => s.id).indexOf(rec.id);
let hasParentBelow = parentIndex > recIndex;
//return hasParentBelow;
console.log('Has Parent Below', hasParentBelow)
return hasParentBelow;
}
function orderByDependant(records) {
Array.prototype.move = function (from, to) {
this.splice(to, 0, this.splice(from, 1)[0]);
};
//order to add null first
records = records.sort(function (a, b) { return a.parentId - b.parentId });
//if the record has parent below, move down in the list
let index;
do {
records.forEach(rec => {
if (!hasParentAbove(records, rec)) {
index = records.indexOf(rec); //find index in collection
records.move(index, index--); //shift down one
console.log('move');
};
});
} while (records.some(rec => !hasParentAbove(records, rec)));
return records;
}
Следующий тестовый пример жасмина может упростить необходимую функциональность.
it('Check method', () => {
let res = YourSorter
expect(res[0].id).toBe(1);
expect(res[1].id).toBe(3);
expect(res[2].id).toBe(4);
expect(res[3].id).toBe(2);
expect(res[4].id).toBe(5);
});
вышел немного глупо :) Я думаю, что лучше использовать пузырь
var arr = [{
"id": 2,
"parentId": 4
},
{
"id": 4,
"parentId": 3
},
{
"id": 5,
"parentId": 2
},
{
"id": 3,
"parentId": null
},
{
"id": 1,
"parentId": null
}
];
arr.sort(function(A, B) {
var aParent = A.parentId * 1;
var bParent = B.parentId * 1;
var a = A.id * 1;
var b = B.id * 1;
if (aParent || bParent) {
return aParent - bParent;
} else {
return a - b
}
});
arr.sort(function(A, B) {
var aParent = A.parentId * 1;
var bParent = B.parentId * 1;
var a = A.id * 1;
var b = B.id * 1;
if (aParent || bParent) {
if (aParent == b) return 1;
else return -1;
}
});
arr.sort(function(A, B) {
var aParent = A.parentId * 1;
var bParent = B.parentId * 1;
var a = A.id * 1;
var b = B.id * 1;
if (aParent || bParent) {
if (aParent == b) return 1;
else return -1;
}
return a - b;
});
console.log(arr);