简体   繁体   English

对键为变量的对象进行排序

[英]Sorting array of objects where key is a variable

I have the following structure: 我有以下结构:

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

And I want to sort it using the following function call: 我想使用以下函数调用对其进行排序:

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

The output would be sorted array of first files, and then folders, like: 输出将是第一个文件,然后是文件夹的排序数组,例如:

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

So I have the following function, calling sort() built-in function on the array, and comparing objects where the given key exists, and skips iteration where the key does not exist in one of the comparators. 所以我有以下函数,在数组上调用内置函数sort() ,比较给定键所在的对象,并跳过其中一个比较器不存在键的迭代。 But it doesn't work, it seems to sort in the completely wrong order. 但这是行不通的,它似乎以完全错误的顺序排序。 What's wrong? 怎么了?

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;
    });
};

The technique called "decorate-sort-undecorate" makes jobs like this easy: 称为“装饰-排序-取消装饰”的技术使这样的工作变得容易:

 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) 

Basically, we convert our array like [item, item...] to an array [ [sort-keys, item], [sort-keys, item]... , then sort that array and finally pull our items back - in the right order. 基本上,我们将数组[item, item...]转换为数组[ [sort-keys, item], [sort-keys, item]... ,然后对该数组进行排序,最后将我们的项目拉回正确的顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM