【问题标题】:Javascript natural sort objectsJavascript 自然排序对象
【发布时间】:2019-03-10 15:45:08
【问题描述】:

我有一个类似的对象数组

array[0] = {id: 1, name: "First"}
array[1] = {id: 2, name: "Second"}

我尝试使用以下方法按name 字段排序:

Array.prototype.alphanumSort = function (caseInsensitive) {
for (var z = 0, t; t = ((typeof this[z] == "string" || typeof this[z] == "undefined") ? this[z] : this[z].name); z++) {
    this[z] = new Array();
    var x = 0, y = -1, n = 0, i, j;

    while (i = (j = t.charAt(x++)).charCodeAt(0)) {
        var m = (i == 46 || (i >= 48 && i <= 57));
        if (m !== n) {
            this[z][++y] = "";
            n = m;
        }
        this[z][y] += j;
    }
}

this.sort(function (a, b) {
    for (var x = 0, aa, bb; (aa = a[x]) && (bb = b[x]); x++) {
        if (caseInsensitive) {
            aa = aa.toLowerCase();
            bb = bb.toLowerCase();
        }
        if (aa !== bb) {
            var c = Number(aa), d = Number(bb);
            if (c == aa && d == bb) {
                return c - d;
            } else return (aa > bb) ? 1 : -1;
        }
    }
    return a.length - b.length;
});

for (var z = 0; z < this.length; z++)
    this[z] = this[z].join("");
}

但我从中返回的列表包含一个数组,其中只有 name 字段,没有相应的 id。为什么会这样? 有没有办法应用这个算法来过滤对象? 我是 JavaScript 新手,所以请温柔一点。

【问题讨论】:

  • 您看过String#localeCompare 和选项吗?
  • 请不要把方法放在原型链上
  • 没关系 @AyushGupta - OP 从来没有真正使用过该代码
  • @NinaScholz 如果我遇到“Ex 10”和“Ex 2”之类的情况怎么办?第二个应该是第一个

标签: javascript arrays sorting object


【解决方案1】:

您可以使用String.prototype.localeCompare

var arr = [
  {id: 1, name: "Third"},
  {id: 2, name: "Fifth"},
  {id: 3, name: "Second"},
  {id: 4, name: "Fourth"},
  {id: 5, name: "First"}
];

arr.sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' }));

console.log(arr);

【讨论】:

  • 在像“First 10”和“First 2”这样的名称排序的情况下,第二个应该是第一个
  • 如果某个对象中没有name 属性,您的代码会将其他字符串与字符串"undefined"进行比较
  • 在这种情况下,我建议创建一个自定义函数来比较两个返回 1、-1、0 到 Array.sort() 的字符串,如下面的 vizsatiz 建议的那样。如果我有空闲时间,我会尝试这样做并更新我的答案。
  • @PR7 不需要自定义函数,见other answer
  • @Dana 无需编写自定义比较函数。您可以使用 localeCompare 函数中的选项。我已经更新了我的答案。 barbsan 谢谢:)
【解决方案2】:

您可以将sorting with map 和String#localeCompare 与options 一起使用

灵敏度

字符串中的哪些差异应导致非零结果值。可能的值是:

  • "base":只有基本字母不同的字符串比较不相等。示例:a ≠ b、a = á、a = A。
  • "accent":只有在基本字母或重音和其他变音符号不同的字符串比较为不相等。示例:a ≠ b、a ≠ á、a = A。
  • "case":只有基本字母或大小写不同的字符串才比较不相等。示例:a ≠ b、a = á、a ≠ A。
  • "variant":基本字母、重音符号和其他变音符号不同的字符串,或者大小写比较不相等。也可以考虑其他差异。示例:a ≠ b、a ≠ á、a ≠ A。

使用“排序”的默认值为“变体”;它依赖于使用“搜索”的语言环境。

数字

是否应使用数字排序规则,例如“1”true 和false;默认为false。此选项可以通过选项属性或通过 Unicode 扩展键设置;如果两者都提供,options 属性优先。实现不需要支持此属性。

var array = ['Ex 10', 'Ex 2', 'a 10.1', 'a 1.1', 'a 10.0', 'a 2.0'];

array.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }));

console.log(array)

【讨论】:

    【解决方案3】:

    这是一个使用 Lodash (https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js) 的示例:

    array[0] = {id: 1, name: "First"}
    array[1] = {id: 2, name: "Second"}
    array = _.orderBy(array, 'name', 'desc')
    

    【讨论】:

      猜你喜欢
      • 2017-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      相关资源
      最近更新 更多