如何在Javascript中通过多个参数对非常大的数据数组进行排序

问题描述 投票:0回答:3

示例:

[{id:1,name:'Jhon',age:'31',address:'XYZ',mobile:'012345678',department:3,section:2,designation:2,.............(34 Types Data)},..........(almost count in 10546)]

根据这些数据,我希望它们首先在部门中升序,然后是部分,然后是名称,然后是名称,如果有多个相同的名称,则使用 id。几乎像下面给出的序列树一样排序。

department=>
|--section=>
|----designation=>
|------name=>
|--------id=>

我已经尝试过以下一种,但顺序仍然不一样。

reurnData.sort(function(a, b) {
  var pA1 = a.section;
  var pA2 = b.section;
  var pB1 = a.department;
  var pB2 = b.department;
  var pC1 = a.designation;
  var pC2 = b.designation;
  var pD1 = a.name;
  var pD2 = b.name;
  var pE1 = a.id;
  var pE2 = b.id;

  if (pA1 < pA2) return -1;
  if (pA1 > pA2) return 1;
  if (pB1 < pB2) return -1;
  if (pB1 > pB2) return 1;
  if (pC1 < pC2) return -1;
  if (pC1 > pC2) return 1;
  if (pD1 < pD2) return -1;
  if (pD1 > pD2) return 1;
  if (pE1 < pE2) return -1;
  if (pE1 > pE2) return 1;
  return 0;
});
javascript arrays json database sorting
3个回答
4
投票

您可以链接整个排序标准。

它会遍历增量,直到找到一个不为零的增量。然后根据

Array#sort
的需要返回比较的差异。

array.sort(function (a, b) {
    return (
        a.department - b.department ||
        a.section - b.section ||
        a.designation - b.designation ||
        a.name.localeCompare(b.name) ||
        a.id - b.id
    );
});

2
投票

@nina-cholz 可以解决您的问题,但我想给您另一个解决方案,该解决方案稍微复杂一点但易于使用,您可以像这样使用它:

array.sort(by("department,section,designation,name,id"))

以下代码:

function by(columns) {
    columns = typeof columns == "string" ? columns.split(",") : columns;

    function compare(a, b) {
        return a > b ? 1 : a < b ? -1 : 0;
    }

    return function (a, b) {
        for (var i in columns) {
            var p = columns[i];
            var it = compare(a[p], b[p]);
            if (it) {
                return it;
            }
        }
        return 0;
    }
}

示例/测试

test("sort with single column", () => {
    let array = [{a: 1}, {a: 3}, {a: 2}];

    expect(array.sort(by("a"))).toEqual([{a: 1}, {a: 2}, {a: 3}]);
});

test("sort column with null values", () => {
    let array = [{a: 1}, {a: null}];

    expect(array.sort(by("a"))).toEqual([{a: null}, {a: 1}]);
});

test("sort string type column", () => {
    let array = [{a: "foo"}, {a: "bar"}];

    expect(array.sort(by("a"))).toEqual([{a: "bar"}, {a: "foo"}]);
});

test("sort by string columns", () => {
    let array = [{a: 1, b: 2}, {a: 1, b: 1}];

    expect(array.sort(by("a,b"))).toEqual([{a: 1, b: 1}, {a: 1, b: 2}]);
});

test("sort by array columns", () => {
    let array = [{a: 1, b: 2}, {a: 1, b: 1}];

    expect(array.sort(by(["a", "b"]))).toEqual([{a: 1, b: 1}, {a: 1, b: 2}]);
});

1
投票

有趣的问题。

我认为它应该有一个动态解决方案,该解决方案应该能够根据按优先级顺序提供的任意数量的属性进行排序。让我们创建一个工厂来为我们提供长度为

n
的假对象数组。

function getFakeObjects(n){  // helper function to get test objects
  return Array(n).fill()
                 .reduce(o => o.concat({p1 : String.fromCharCode(...Array(5).fill().map(_ => ~~(Math.random()*26)+97)),
                                        p2 : ~~(Math.random()*5)+1,
                                        p3 : ["Istanbul","Moscow","New York","Tokyo","Rio","Accra"][~~(Math.random()*6)],
                                        p4 : ~~(Math.random()*2+1)+String.fromCharCode(~~(Math.random()*3)+65)
                                       }),[]);
}

function multiLevelSorter(os,ps){
  return os.sort(function(a,b){
                   var p = ps.find(f => a[f] !== b[f]);
                   return a[p] < b[p] ? -1 : 1;
                 });
}

var fakes = getFakeObjects(50),
sortOrder = ["p3","p2","p4","p1"],
   sorted = multiLevelSorter(fakes,sortOrder);
sorted.forEach(o => console.log("{p1:", o.p1,"p2:",o.p2,"p3:",o.p3,"p4:",o.p4,"}"));
.as-console-wrapper { max-height: 100% !important; top: 0; }

© www.soinside.com 2019 - 2024. All rights reserved.