对键是变量的对象数组进行排序

时间:2016-09-15 12:50:44

标签: javascript arrays sorting

我有以下结构:

var arrOfObjects = [
  {
    folder: {id: 2},
    children: []
  },
  {
    file: {id: 3},
    children: []
  },
  {
    file: {id: 4},
    children: []
  },
  {
    folder: {id: 1},
    children: []
  },
];

我想使用以下函数调用对其进行排序:

sortArrOfObjects(arrOfObjects, {
  types: [
    ['file']
  ],
  index: 'id',
  order: 'asc'
});
sortArrOfObjects(arrOfObjects, {
  types: [
    ['folder']
  ],
  index: 'id',
  order: 'asc'
});

输出将排序第一个文件的数组,然后是文件夹,如:

var arrOfObjects = [
  {
    file: {id: 3},
    children: []
  },
  {
    file: {id: 4},
    children: []
  },
  {
    folder: {id: 1},
    children: []
  },
  {
    folder: {id: 2},
    children: []
  },
];

所以我有以下函数,在数组上调用sort()内置函数,并比较给定键存在的对象,并跳过其中一个比较器中不存在键的迭代。但它不起作用,似乎排序完全错误。怎么了?

function sortArrayOfObjects(arr, sortBy) {
    arr.sort(function (a, b) {
        var first = '';
        var second = '';
        for (var i = 0; i < sortBy.types.length; i++) {
            switch (sortBy.types[i].length) {
                case 1:
                    if (a[sortBy.types[i][0]] != undefined) {
                        first = a[sortBy.types[i][0]][sortBy.index].toString().toLowerCase();
                    } else {
                        return;
                    }
                    if (b[sortBy.types[i][0]] != undefined) {
                        second = b[sortBy.types[i][0]][sortBy.index].toString().toLowerCase();
                    } else {
                        return;
                    }
                    break;
                case 2:
                    // not implemented yet
                    break;
                default:
                    break;
            }
        }
        if (first > second) {
            return (sortBy.order == 'asc') ? 1 : -1;
        }
        if (first < second) {
            return (sortBy.order == 'asc') ? -1 : 1;
        }
        return 0;
    });
};

1 个答案:

答案 0 :(得分:2)

这种称为“decorate-sort-undecorate”的技术使这样的工作变得简单:

var arrOfObjects = [
    {
        folder: {id: 2},
        children: []
    },
    {
        file: {id: 3},
        children: []
    },
    {
        file: {id: 4},
        children: []
    },
    {
        folder: {id: 1},
        children: []
    },
];

result = arrOfObjects
    .map(obj => ('file' in obj) ? [1, obj.file.id, obj] : [2, obj.folder.id, obj])
    .sort((a, b) => a[0] - b[0] || a[1] - b[1])
    .map(x => x[2]);


console.log(result)

基本上,我们将像[item, item...]这样的数组转换为数组[ [sort-keys, item], [sort-keys, item]...,然后对该数组进行排序,最后以正确的顺序拉回我们的项目。