在嵌套键上排序数组

时间:2016-01-08 16:55:24

标签: javascript arrays sorting

我正在使用此函数根据对象键对数组进行排序:

function keysrt(arr, key, reverse) {
    var sortOrder = 1;
    if(reverse){
        sortOrder = -1;
    }
    return arr.sort(function(a, b) {
        var x = a[key],
            y = b[key];

        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}   

它适用于这种类型的数组,其中键位于第一级:

var a = [ 
    { id: 0, last: 'Anne'},
    { id: 1, last: 'Odine'},
    { id: 2, last: 'Caroline'}
]

keysrt(a, 'last');

如何使用此示例,其中title键是嵌套

var b = [ 
    { id: 0, last: 'Anne',     data:{title: 'habc'}},
    { id: 1, last: 'Odine',    data:{title: 'asdf'}},
    { id: 2, last: 'Prentice', data:{title: 'tzuio'}}
]

keysrt(b, 'title');

5 个答案:

答案 0 :(得分:7)

对于这个想法,“key”变量变为一个键数组:然后指定要排序的嵌套值的“路径”。

function keysrt(arr, keyArr, reverse) {
    var sortOrder = 1;
    if(reverse)sortOrder = -1;
    return arr.sort(function(a, b) {
        var x=a,y=b;
        for (var i=0; i < keyArr.length; i++) {
          x = x[keyArr[i]];
          y = y[keyArr[i]];
        }
        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
} 

keysrt(b,['data','title']);

答案 1 :(得分:3)

如果您准备更改功能签名和函数调用,这是一个简单的解决方案 -

prop

此处,key表示外部对象,var y = b[prop][key]表示嵌套键。

因此,b.data.title基本上意味着您正在访问PersonID int; Name string; ICollection<FavFood> FavFoods; ICollection<FavShow> FavShows;

希望它有所帮助:)快乐的编码!

答案 2 :(得分:2)

如果你需要使它成为通用的,我认为你可以传入一个函数,它将从数组项中检索值以进行比较:

function keysrt(arr, reverse, getValueFn) {
    var sortOrder = 1;
    if(reverse)sortOrder = -1;
    return arr.sort(function(a, b) {
        var x = getValueFn(a); var y = getValueFn(b);
        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}

这样你就可以像:

一样使用它
keysrt(b, true, function(a){return a.data.title})   

答案 3 :(得分:1)

要查找嵌套属性值,任意数量的级别,您可以使用JSON.stringify作为步行对象的方式:

function get_nested_value(obj, prop) {
  var result;
  JSON.stringify(obj, function(key, value) {
    if (key === prop) result = value;
  });
  return result;
}

现在:

function keysrt(arr, key, reverse) {
    var sortOrder = 1;
    if(reverse){
        sortOrder = -1;
    }
    return arr.sort(function(a, b) {
        var x = get_nested_value(a, key);
            y = get_nested_value(b, key);

        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}  

答案 4 :(得分:0)

您可以使用以下代码获得工作示例:

function keysrt(arr, key, reverse) {
    var sortOrder = reverse ? -1 : 1;

    return arr.sort(function(a, b) {
        var x,y;

        if(typeof a[key] !== "undefined") {
          x = a[key]; 
          y = b[key];
        } else {
          for(var prop in a) {
            if(a[prop][key] !== "undefined") {
              x = a[prop][key];
              y = b[prop][key];
            }
          }
        }

        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}   

但我会建议更通用的解决方案

function keysrt(arr, path, reverse) {
    var sortOrder = reverse ? -1 : 1;
    var pathSplitted = path.split(".");

    if(arr.length <= 1) {
      return arr;
    }

    return arr.sort(function(a, b) {
        var x = a;
        var y = b;

        pathSplitted.forEach(function(key) {
          x = x[key];
          y = y[key];
        });     

        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}   

其中一个可以像这样提供排序字段的路径

var sorted = keysrt(b, 'data.title');

演示:http://jsbin.com/cosugawoga/edit?js,console