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

时间:2017-03-18 09:13:13

标签: javascript arrays json database sorting

示例:

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

4 个答案:

答案 0 :(得分:3)

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

它经过增量直到找到一个delta,它不是零。然后根据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
    );
});

答案 1 :(得分:2)

@ nina-cholz可以解决您的问题,我想给您另一个解决方案,这个解决方案更复杂但更易于使用。然后您可以将其用作:array.sort(by("department,section,designation,name,id"))

代码beolow:

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

答案 2 :(得分:1)

有趣的问题。

我认为它值得一个动态解决方案,该解决方案应该对按优先级顺序提供的任意数量的属性进行排序有效。让我们创建一个工厂,为我们提供一系列长度为n的假对象。

&#13;
&#13;
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,"}"));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 3 :(得分:1)

在javascript for循环中,使用过的函数将一直工作。但是在NodeJS的情况下,它是一个回调地狱,无论我们使用多少函数,它有时会松开大循环上的序列。因此,对于大型数据,我不认为NodeJS是一个很好的选择继续。