Сортировать массив по родительским отношениям

1

Я хочу сортировать массив по родительским отношениям. В принципе, я хочу, чтобы все записи были в порядке, где родительский индекс всегда должен быть выше дочернего индекса. Родитель может быть связан только один раз, поэтому единственная проблема заключается в том, что ребенок может быть родителем. Источник данных будет выглядеть так:

[{
            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);

    });
  • 0
    Также обратите внимание на его ECMA 6 дружественных,
Теги:
sorting

1 ответ

0

вышел немного глупо :) Я думаю, что лучше использовать пузырь

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);
  • 0
    поэтому в этом случае я хочу, чтобы родитель был указан перед ребенком для каждой записи. поэтому в случае, когда ребенок также является родителем, я хочу, чтобы этот список был указан перед его ребенком. (Родитель может быть связан только один раз). дело не в сортировке по идентификатору, а по отношению к родителю.
  • 0
    Обновлен вопрос о включении жасмина для иллюстрации правильного результата.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню