javascript - 按子属性(可能缺失)对对象的 javascript 数组进行排序

标签 javascript arrays sorting

我有一个大型数据集(从 400 到 4,000 个对象存储在一个数组中),我试图通过用户选择的字段过滤它们。

现在我正在使用这个函数,在另一个 SO 问题上找到:

var sort = function (prop, arr) {
    prop = prop.split('.');
    var len = prop.length;

    arr.sort(function (a, b) {
        var i = 0;
        while( i < len ) {
            a = a[prop[i]];
            b = b[prop[i]];
            i++;
        }
        if (a < b) {
            return -1;
        } else if (a > b) {
            return 1;
        } else {
            return 0;
        }
    });
    return arr;
};

示例数据 - 我想按 friends 计数对对象进行排序:

var data = [
    {
        name: 'Jim',
        friends: {
            count: 20,
            url: 'http://foo.com'
        }
    },{
        name: 'Lucy',
    },{
        name: 'Phil',
        friends: {
            count: 450,
            url: 'http://moo.com'
        }
    }
];

请注意“Lucy”如何没有 friends 对象 - 所以当我运行 sort('friends.count', data); 时,脚本会中断。

理想情况下,我希望将不具有我排序所依据的属性的对象放在数组的末尾。关于如何实现这一点有什么想法吗?

最佳答案

例如,

var data = [
    {
        name: 'Jim',
        friends: {
            count: 20,
            url: 'http://foo.com'
        }
    },{
        name: 'Lucy',
    },{
        name: 'Phil',
        friends: {
            count: 450,
            url: 'http://moo.com'
        }
    }
];

safeGet = function(obj, prop, defaultValue) {
  try {
    return obj[prop]
  } catch(e) {
    return defaultValue
  }
}


data.sort(function(x, y) {
  return (
    safeGet(x.friends, 'count', Infinity) - 
    safeGet(y.friends, 'count', Infinity));
});

document.write("<pre>" + JSON.stringify(data,0,3));

如果整个属性链 (friends.count) 是动态的,更改 safeGet 以便它迭代 Prop 列表:

var data = [
    {
        name: 'Jim',
        friends: {
            count: 20,
            url: 'http://foo.com'
        }
    },{
        name: 'Lucy',
    },{
        name: 'Phil',
        friends: {
            count: 450,
            url: 'http://moo.com'
        }
    }
];

safeGet = function(obj, props, defaultValue) {
  try {
    return props.split('.').reduce(function(obj, p) {
      return obj[p];
    }, obj);
  } catch(e) {
    return defaultValue
  }
}


data.sort(function(x, y) {
  return (
    safeGet(x, 'friends.count', Infinity) - 
    safeGet(y, 'friends.count', Infinity));
});

document.write("<pre>" + JSON.stringify(data,0,3));

如果您想让没有 friend 的人先走,而不是最后走,请将 Infinity 更改为 -Infinity

关于javascript - 按子属性(可能缺失)对对象的 javascript 数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29058568/

相关文章:

JavaScript Object.create 现有对象的样式

javascript - jquery 图像和背景淡入淡出 onclick

c++ - "p"数组如何使用 C++ std::normal_distribution 在以下代码中存储值?

c++ - 数组中的第 K 个和

java - 用户输入int到Array然后使用冒泡排序对数字进行排序

javascript - 专家css选择器请在里面

javascript - 如何使用angularjs在 float 条形图点击事件上显示数据列表

java - String vs Char Array vs String Builder(效率表现)

php - 合并两个数组以使整数值尽可能接近相等

c - 堆排序 : how to correct my coding and to implement my logic?