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

发布于 2025-01-18 08:09:20 字数 1448 浏览 2 评论 0 原文

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

我得到的顺序是 [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));

I am trying to sort an array of objects by the name field but the ordering is wrong.

The order I am getting is [1, 10, 11, 2, 20, 21, 3]

Instead of [1, 2, 3, .... 10, 11, 20, 21]

It is sorting but putting 10 ahead of 2

Here is the code I am currently using.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爺獨霸怡葒院 2025-01-25 08:09:20

人们可以给出数字 排序选项 href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare" rel="nofollow noreferrer">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; }

One could give the numeric sorting option of String.prototype.localeCompare a try ...

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

海拔太高太耀眼 2025-01-25 08:09:20

顺序是正确的。字符串“Action 10”将大于 Action 1 且小于 Action 2,因为字符串比较是逐个字符进行的。

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

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

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

  • 如果pxpy的前缀,则返回true

k为最小非负整数,使得px内位置k处的字符与位置处的字符不同kpy 内。 (必须有这样一个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;
  }

如果您想根据语义含义对事物进行排序 of name,您需要将字符串划分为非数字段和数字段的列表,将数字位转换为数字,然后按从左到右的顺序比较这些段向右。

The ordering is correct. The string "Action 10" collates greater than Action 1 and less than Action 2, because string comparison is done on a character by character basis.

The algorithm for string comparision is found here: https://262.ecma-international.org/5.1/#sec-11.8.5

[If] both px and py are Strings

  • If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.)

  • If px is a prefix of py, return true.

Let k be the smallest nonnegative integer such that the character at position k within px is different from the character at position k within py. (There must be such a k, for neither String is a prefix of the other.)

  • Let m be the integer that is the code unit value for the character at position k within px.

  • Let n be the integer that is the code unit value for the character at position k within py.

  • If m < n, return true. Otherwise, return false.

Or, as a javascript function, the expression str1 < str2 is evaluated as if this function were invoked (not that anybody sane would implement the algorithm as described in the spec):

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

If you want to order things according to the semantic meaning of name, you'll need to partition the string into a list of its non-numeric and numeric segments, convert the numeric bits into numbers, and then compare the segments in order from left to right.

孤独患者 2025-01-25 08:09:20

您可以使用正则表达式:

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

DEMO

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

You can use regular expressions:

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

DEMO

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

离线来电— 2025-01-25 08:09:20
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));

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文