【问题标题】:Performing a case sensitive string sorting in TypeScript在 TypeScript 中执行区分大小写的字符串排序
【发布时间】:2020-07-19 17:43:13
【问题描述】:

我有一个看起来像的数组

var arr = [{'Id':'1','Value':'Desk'},
     {'Id':'2','Value':'skool'},
     {'Id':'3','Value':'OT'},
     {'Id':'4','Value':'sector'},
     {'Id':'5','Value':'Security'},
     {'Id':'6','Value':'Zebra'},

我想对这个数组进行排序以获得结果

[
  { Id: '1', Value: 'Desk' },
  { Id: '3', Value: 'OT' },
  { Id: '4', Value: 'sector' },
  { Id: '2', Value: 'skool' },
  { Id: '5', Value: 'Security' },
  { Id: '6', Value: 'Zebra' }
]

我试过了

arr.sort((a,b) => (a.Value.toLocaleLowerCase() > b.Value.toLocaleLowerCase()) ? 1 : ((b.Value.toLocaleLowerCase() > a.Value.toLocaleLowerCase()) ? -1 : 0)); 

这给了我一个结果

[
  { Id: '1', Value: 'Desk' },
  { Id: '3', Value: 'OT' },
  { Id: '4', Value: 'sector' },
  { Id: '5', Value: 'Security' },
  { Id: '2', Value: 'skool' },
  { Id: '6', Value: 'Zebra' }
]

区别是skoolSecurity 的顺序。我希望我所有的小写字母先出现,然后是大写字母。我可以尝试什么来实现这一目标?

【问题讨论】:

  • toLocaleLowerCase 应该做什么?
  • 它看起来像stackoverflow.com/questions/62316839/…(嗯,在答案中你有 parentId,这里有,如果 Value[0] 是小写,则 parentId=Value[0].toUpperCase() 否则为 null)

标签: javascript angular typescript sorting


【解决方案1】:

您想按字母顺序还是按大小写排序?如果您按字母顺序排序,则无法在skool 之后得到Security,因为按字母顺序,e 位于k 之前。

如果你愿意的话-

  • 如果两个单词的首字母相同,则先小写排序,而不考虑进一步的字母顺序。

在这种情况下,您可以使用以下 -

var arr = [{
    Id: '1',
    Value: 'Desk'
  },
  {
    Id: '3',
    Value: 'OT'
  },
  {
    Id: '4',
    Value: 'sector'
  },
  {
    Id: '2',
    Value: 'skool'
  },
  {
    Id: '5',
    Value: 'Security'
  },
  {
    Id: '6',
    Value: 'Zebra'
  }
];


arr.sort(function(a, b) {
  //if exactly same strings, return 0
  if (a.Value === b.Value)
    return 0;
  //if first case of a and b are unequal return based on case
  if (a.Value.toLocaleLowerCase()[0] === b.Value.toLocaleLowerCase()[0] && a.Value[0] !== b.Value[0])
    return a.Value[0] < b.Value[0] ? 1 : -1;
  //Now return 0 if both are equal in lower case else return 1 or -1 depending on comparison below
  if (a.Value.toLocaleLowerCase() === b.Value.toLocaleLowerCase())
    return 0;
  return a.Value.toLocaleLowerCase() > b.Value.toLocaleLowerCase() ? 1 : -1;

});


//Apparently below code is not the exactly right way to do it, so use the above method
//arr.sort((a, b) => (a.Value.toLocaleLowerCase()[0] === b.Value.toLocaleLowerCase()[0]) ? (a.Value[0] > b.Value.[0]?1:-1) : (a.Value.toLocaleLowerCase() > b.Value.toLocaleLowerCase()?1:-1));

console.log(arr);

在上面的sn-p中,如果任意两个单词的首字母相同,则按照首字母的大小写进行排序。在所有其他情况下,它将按字母顺序排序。

编辑:根据评论建议,对于 TS 中的排序函数,它应该返回 -

  • 1 : 当a &gt; b,
  • 0 : 当a === b
  • -1:当a &lt; b

因此,答案中提到了一个更正确(以及可读)的版本。

希望这会有所帮助!

【讨论】:

  • 嗨,我只希望结果是这样的,但是当我尝试在我的打字稿代码中执行相同的操作时,我收到错误消息 Type 'boolean' is not assignable to type 'number'
  • @cvg 我没用过打字稿。您确定您在排序功能中遇到错误吗?因为我认为这个函数是 JS 语法 正确的。
  • @Abhishek 该函数在语法上是正确的,但 it returns a boolean, not a number
  • @cvg 我已经编辑了答案,现在该功能应该可以正常工作了。
  • 你永远不会返回-1(或负值)。所以现在它不返回布尔 type 但它仍然只有两个值,而不是三个。这可能会导致不正确的排序结果。
【解决方案2】:

试试这个:

var arr = [{'Id':'1','Value':'Desk'},{'Id':'2','Value':'skool'},{'Id':'3','Value':'OT'},{'Id':'4','Value':'sector'},{'Id':'5','Value':'Security'},{'Id':'6','Value':'Zebra'}];
var sort = (a, b) => a > b ? 1 : (a < b ? -1 : 0);
var sorted = arr.sort((a,b) => 
  sort(a.Value[0].toLowerCase(), b.Value[0].toLowerCase()) || 
  -sort(a.Value[0], b.Value[0]) ||
  sort(a.Value, b.Value));
console.log(sorted);

【讨论】:

  • 这不能回答 OP 的问题。要求是在扇区之后对 skool 进行排序,即当第一个字符大小写相同时,按字母顺序排序,而在您的情况下,它没有相应地排序。请编辑帖子以符合要求
【解决方案3】:

只是在你的技巧包里,如果你想先把所有小写字母按字母顺序排列,然后再用所有大写字母,你可以使用这个:

arr.sort(function (a, b) {
    if (a.Value[0] === a.Value[0].toLowerCase() && b.Value[0] === b.Value[0].toLowerCase() ||
        a.Value[0] === a.Value[0].toUpperCase() && b.Value[0] === b.Value[0].toUpperCase()) {
        return a.Value.localeCompare(b.Value);
    }
    if (a.Value[0] === a.Value[0].toLowerCase()) {
        return -1;
    }
    return 1;
});

这是输出:

[ { Id: '4', Value: 'sector' },
  { Id: '2', Value: 'skool' },
  { Id: '1', Value: 'Desk' },
  { Id: '3', Value: 'OT' },
  { Id: '5', Value: 'Security' },
  { Id: '6', Value: 'Zebra' } ]

【讨论】:

  • 请看一下预期的输出。您的输出可以用一个简单的arr.sort(function (a, b) {a&gt;b?1:-1}); 进行归档
  • 预期的输出顺序是:Desk, OT, sector, skool, Security, Zebra。请看一下这个问题。有明确显示预期输出的演示
  • 我明白这一点。他最初的排序来自我在他制作的重复线程中的评论。其实我们之前在贴子里聊过,所以我想给他这个药水,因为要求有点不清楚。
猜你喜欢
  • 2012-02-18
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 2018-09-29
  • 2016-04-02
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
相关资源
最近更新 更多