如何根据对象的字母数字名称值正确对对象数组进行排序?

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

我试图按名称字段对对象数组进行排序,但顺序错误。

我得到的顺序是 [1, 10, 11, 2, 20, 21, 3]

而不是 [1, 2, 3, .... 10, 11, 20, 21]

正在排序,但将 10 放在 2 之前

这是我当前使用的代码。

const arr = [
    
    {
        "name": "Action 10",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 11",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 2",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 20",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 21",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 3",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 4",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 5",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 6",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 1",
        "color": "transparent",
        "type": "components"
    }
]

function sorter(a, b) {
    if (a.name < b.name) return -1;
    if (a.name > b.name) return 1;
    return 0;
}

console.log(arr.sort(sorter));

javascript arrays sorting alphanumeric
4个回答
3
投票

可以尝试一下

numeric
String.prototype.localeCompare
排序选项
...

const arr = [{
  name: "Action 10", color: "transparent", type: "components"
}, {
  name: "Action 11", color: "transparent", type: "components"
}, {
  name: "Action 2", color: "transparent", type: "components"
}, {
  name: "Action 20", color: "transparent", type: "components"
}, {
  name: "Action 21", color: "transparent", type: "components"
}, {
  name: "Action 3", color: "transparent", type: "components"
}, {
  name: "Action 4", color: "transparent", type: "components"
}, {
  name: "Action 5", color: "transparent", type: "components"
}, {
  name: "Action 6", color: "transparent", type: "components"
}, {
  name: "Action 1", color: "transparent", type: "components"
}];

function sorter(a, b) {
  return a.name.localeCompare(b.name, undefined, { numeric: true });
}
console.log(arr.sort(sorter));
.as-console-wrapper { min-height: 100%!important; top: 0; }


1
投票

顺序正确。字符串“Action 10”将大于

Action 1
且小于
Action 2
,因为字符串比较是逐个字符进行的。

字符串比较的算法可以在这里找到:https://262.ecma-international.org/5.1/#sec-11.8.5

[如果] px 和 py 都是字符串

  • 如果pypx的前缀,则返回

    false
    。 (如果 q 可以是连接 p 和其他字符串 r 的结果,则字符串值 p 是字符串值 q 的前缀。请注意,任何字符串都是其自身的前缀,因为 r 可能是空字符串。)

  • 如果pxpy的前缀,则返回

    true

k为最小非负整数,使得px内位置k处的字符与py内位置k处的字符不同。 (必须有这样一个 k,因为两个字符串都不是另一个字符串的前缀。)

  • m 为整数,即 px 内位置 k 处的字符的代码单元值。

  • n 为整数,即 py 内位置 k 处的字符的代码单元值。

  • 如果m < n,则返回

    true
    。否则,返回
    false

或者,作为一个 javascript 函数,表达式

str1 < str2
的计算就像调用该函数一样(并不是任何理智的人都会实现规范中描述的算法):

function lt( px, py ) {
    const prefixOf = (x,y) => x.slice(0,y.length) === y;

    if ( prefixOf(px,py) ) return false;
    if ( prefixOf(py,px) ) return true;

    let k = 0 ;
    while ( px[k] === py[k] ) {
        ++k;
    }
 
    m = px.charCodeAt(k);
    n = py.charCodeAt(k);

    return m < n ? true : false;
  }

如果您想根据name语义

对事物进行排序,您需要将字符串划分为非数字和数字段的列表,将数字位转换为数字,然后按从左到右的顺序比较片段。


0
投票

您可以使用正则表达式:

const sorter = (a, b) => +a.name.match(/\d+/) - +b.name.match(/\d+/);

演示

const arr = [{"name": "Action 10","color": "transparent","type": "components"}, {"name": "Action 11","color": "transparent","type": "components"}, {"name": "Action 2","color": "transparent","type": "components"}, {"name": "Action 20","color": "transparent","type": "components"}, {"name": "Action 21","color": "transparent","type": "components"}, {"name": "Action 3","color": "transparent","type": "components"}, {"name": "Action 4","color": "transparent","type": "components"}, {"name": "Action 5","color": "transparent","type": "components"}, {"name": "Action 6","color": "transparent","type": "components"}, {"name": "Action 1","color": "transparent","type": "components"}]

function sorter(a, b) {
    return +a.name.match(/\d+/)[0] - +b.name.match(/\d+/)[0];
}

console.log(arr.sort(sorter));


0
投票

const arr = [{"name": "Action 10","color": "transparent","type": "components"}, {"name": "Action 11","color": "transparent","type": "components"}, {"name": "12Action 2","color": "transparent","type": "components"}, {"name": "Action","color": "transparent","type": "components"}, {"name": "Action 21","color": "transparent","type": "components"}, {"name": "Action 3","color": "transparent","type": "components"}, {"name": "Action 4","color": "transparent","type": "components"}, {"name": "Action 5","color": "transparent","type": "components"}, {"name": "Action 6","color": "transparent","type": "components"}, {"name": "Action 1","color": "transparent","type": "components"}]

function sorter(a, b) {
    return +a.name.match(/\d+/)[0] - +b.name.match(/\d+/)[0];
}

console.log(arr.sort(sorter));

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