按具有点分隔数字的属性对对象数组进行排序

4

我有一个像这样的对象数组

var arr = [{
    "id": "1",
    "Title": "Object1",
    "SectionId": "1.2.1"
}, {
    "id": "2",
    "Title": "Object2",
    "SectionId": "1.1.2"
}, {
    "id": "3",
    "Title": "Object3",
    "SectionId": "1.0.1"
}, {
    "id": "4",
    "Title": "Object4",
    "SectionId": "1"
}];

sectionId是由数字和点号分隔的。我该如何根据sectionId属性按升序或降序对数组进行排序?


请看这里 https://jsfiddle.net/62cuna7w/2/ - Ionut Necula
3个回答

4

受到 使用 map 排序 的启发。

function customSort(d, order) {
    var sort = {
            asc: function (a, b) {
                var l = 0, m = Math.min(a.value.length, b.value.length);
                while (l < m && a.value[l] === b.value[l]) {
                    l++;
                }
                return l === m ? a.value.length - b.value.length : a.value[l] - b.value[l];
            },
            desc: function (a, b) {
                return sort.asc(b, a);
            }
        },

        // temporary array holds objects with position and sort-value
        mapped = d.map(function (el, i) {
            return { index: i, value: el.SectionId.split('.').map(Number) };
        });

    // sorting the mapped array containing the reduced values
    mapped.sort(sort[order] || sort.asc);

    // container for the resulting order
    return mapped.map(function (el) {
        return d[el.index];
    });
}

var arr = [{ "id": "1", "Title": "Object1", "SectionId": "1.2.1" }, { "id": "2", "Title": "Object2", "SectionId": "1.1.2" }, { "id": "3", "Title": "Object3", "SectionId": "1.0.1" }, { "id": "4", "Title": "Object4", "SectionId": "1.1.10" }, { "id": "5", "Title": "Object5", "SectionId": "1" }];

document.write('<pre>sorted array asc ' + JSON.stringify(customSort(arr), 0, 4) + '</pre>');
document.write('<pre>sorted array desc ' + JSON.stringify(customSort(arr, 'desc'), 0, 4) + '</pre>');
document.write('<pre>original array ' + JSON.stringify(arr, 0, 4) + '</pre>');


1
var sort = function(isAsc) {
    return function(a, b) {
        var x = a.SectionId.split('.').map(Number)
        var y = b.SectionId.split('.').map(Number)
        for (var i = 0; i < 3; i++) {
            if (x[i] > y[i]) return isAsc ? 1 : -1;
            if (x[i] < y[i]) return isAsc ? -1 : 1;
            if (!isNaN(x[i]) && isNaN(y[i])) return isAsc ? 1 : -1;
            if (isNaN(x[i]) && !isNaN(y[i])) return isAsc ? -1 : 1;
        }
        return 0;
    }
}

var acs = sort(true)
var desc = sort()

arr.sort(acs)
arr.sort(desc)

它无法捕获问题,因为由于字符串比较,它将在1.1.2之前对1.1.10进行排序。 - Nina Scholz
这很奇怪,不是吗? - Nina Scholz
@NinaScholz 有什么奇怪的? - isvforall
每次回调时都要进行拆分。 - Nina Scholz
@NinaScholz 对于每种排序,它们都有不同的逻辑。 - isvforall
让我们在聊天中继续这个讨论:点击此处进入聊天室 - isvforall

0
var arr = [{
    "id": "1",
    "Title": "Object1",
    "SectionId": "1.2.1"
}, {
    "id": "2",
    "Title": "Object2",
    "SectionId": "1.1.2"
}, {
    "id": "3",
    "Title": "Object3",
    "SectionId": "1.0.1"
}, {
    "id": "4",
    "Title": "Object4",
    "SectionId": "1"
}];

const result = arr.sort((a, b) => (a.SectionId > b.SectionId) ? 1 : -1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接