按父关系对数组排序

时间:2018-11-01 06:38:14

标签: javascript sorting

我想按父级关系对数组进行排序。基本上,我希望所有记录都按父索引必须始终高于子索引的顺序排列。 父母只能链接一次,因此这里唯一的问题是孩子可以是父母。 数据源将如下所示:

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

    });

1 个答案:

答案 0 :(得分: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);