Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >C#与F#中的默认排序

C#与F#中的默认排序
EN

Stack Overflow用户
提问于 2015-06-23 09:31:24
回答 4查看 774关注 0票数 18

考虑一下分别在C#F#中对字符串进行排序的两段代码:

C#:

代码语言:javascript
运行
AI代码解释
复制
var strings = new[] { "Tea and Coffee", "Telephone", "TV" };
var orderedStrings = strings.OrderBy(s => s).ToArray();

F#:

代码语言:javascript
运行
AI代码解释
复制
let strings = [| "Tea and Coffee"; "Telephone"; "TV" |]
let orderedStrings =
    strings
    |> Seq.sortBy (fun s -> s)
    |> Seq.toArray

这两段代码返回不同的结果:

  • C#:茶和咖啡,电话,TV
  • F#:电视,茶和咖啡,电话

在我的特定案例中,我需要将这两种语言之间的排序逻辑关联起来(一种是产品代码,另一种是测试断言的一部分)。这提出了几个问题:

  • 排序逻辑上的差异有没有潜在的原因?
  • 在my
  • 中克服这个“问题”的推荐方法是什么这一现象特定于字符串,或者它也适用于其他.NET类型?

编辑

为了回应几个试探性的评论,运行下面的片段揭示了更多关于这种排序差异的确切性质:

F#:

代码语言:javascript
运行
AI代码解释
复制
let strings = [| "UV"; "Uv"; "uV"; "uv"; "Tv"; "TV"; "tv"; "tV" |]
let orderedStrings =
    strings
    |> Seq.sortBy (fun s -> s)
    |> Seq.toArray

C#:

代码语言:javascript
运行
AI代码解释
复制
var strings = new[] { "UV", "Uv", "uv", "uV", "TV", "tV", "Tv", "tv" };
var orderedStrings = strings.OrderBy(s => s).ToArray();

提供:

  • C#:Tv,TV,tV,TV,uv,uV,Uv,UV
  • F#:Tv,tV,UV,Uv,tv,tv,uV,uv

字符串的字典顺序因字符的基本顺序不同而有所不同:

"aAbBcCdD...tTuUvV..."

  • F#:"ABC..TUV..Zabc..tuv.."

  • C#
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-06-23 21:55:12

请参阅language spec的8.15.6节。

字符串、数组和本机整数都有特殊的比较语义,如果实现了IComparable (对各种优化进行取模,会产生相同的结果),那么其他所有的东西都会被用来比较。

特别是,与大多数默认使用区域性比较的.NET不同,F#字符串在默认情况下使用序号比较。

这显然是F#和其他.NET语言之间令人困惑的不兼容性,但它确实有一些好处:

  • OCAML compat
  • 字符串和字符比较在
    • C# OCAML中保持一致

编辑:

注意,声明"F#使用区分大小写的字符串比较“是有误导性的(虽然不是不正确的)。F#使用序号比较,这比区分大小写更严格。

代码语言:javascript
运行
AI代码解释
复制
// case-sensitive comparison
StringComparer.InvariantCulture.Compare("[", "A") // -1
StringComparer.InvariantCulture.Compare("[", "a") // -1

// ordinal comparison
// (recall, '[' lands between upper- and lower-case chars in the ASCII table)
compare "[" "A"  // 26
compare "[" "a"  // -6
票数 6
EN

Stack Overflow用户

发布于 2015-06-23 09:49:58

不同的库对字符串进行不同的默认比较操作。F#严格默认区分大小写,而LINQ不区分大小写。

List.sortWithArray.sortWith都允许指定比较。Enumerable.OrderBy的过载也是如此。

然而,Seq模块似乎没有对应的模块(并且在4.6中没有添加一个模块)。

具体问题:

排序逻辑上的差异有没有潜在的原因?

两种排序都是有效的。在英语中,不敏感似乎更自然,因为这是我们习惯的。但这并不能让它变得更正确。

在我的情况下,解决这个“问题”的推荐方法是什么?

明确说明这种比较。

是特定于字符串的现象,还是它也适用于其他.NET类型?

char也会受到影响。以及存在多于一种可能排序的任何其他类型(例如,A People类型:您可以根据具体要求按姓名或出生日期排序)。

票数 6
EN

Stack Overflow用户

发布于 2015-06-23 17:04:24

这与C#与F#,甚至与IComparable无关,而只是由于库中不同的排序实现。

TL;DR;版本是对字符串进行排序可以得到不同的结果:

代码语言:javascript
运行
AI代码解释
复制
"tv" < "TV"  // false
"tv".CompareTo("TV")  // -1 => implies "tv" *is* smaller than "TV"

或者更清楚的是:

代码语言:javascript
运行
AI代码解释
复制
"a" < "A"  // false
"a".CompareTo("A")  // -1 => implies "a" is smaller than "A"

这是因为CompareTo使用当前的区域性(see MSDN)

我们可以通过一些不同的例子来看看这是如何在实践中发挥作用的。

如果我们使用标准的F#排序,我们会得到大写优先的结果:

代码语言:javascript
运行
AI代码解释
复制
let strings = [ "UV"; "Uv"; "uV"; "uv"; "Tv"; "TV"; "tv"; "tV" ]

strings |> List.sort 
// ["TV"; "Tv"; "UV"; "Uv"; "tV"; "tv"; "uV"; "uv"]

即使我们对IComparable进行强制转换,也会得到相同的结果:

代码语言:javascript
运行
AI代码解释
复制
strings |> Seq.cast<IComparable> |> Seq.sort |> Seq.toList
// ["TV"; "Tv"; "UV"; "Uv"; "tV"; "tv"; "uV"; "uv"]

另一方面,如果我们从F#使用Linq,我们会得到与C#代码相同的结果:

代码语言:javascript
运行
AI代码解释
复制
open System.Linq
strings.OrderBy(fun s -> s).ToArray()
// [|"tv"; "tV"; "Tv"; "TV"; "uv"; "uV"; "Uv"; "UV"|]

根据MSDN的说法,OrderBy方法“使用缺省的比较器缺省值来比较键”。

默认情况下,F#库不使用Comparer,但我们可以使用sortWith

代码语言:javascript
运行
AI代码解释
复制
open System.Collections.Generic
let comparer = Comparer<string>.Default

现在,当我们进行这种排序时,我们得到了与LINQ OrderBy相同的结果

代码语言:javascript
运行
AI代码解释
复制
strings |> List.sortWith (fun x y -> comparer.Compare(x,y))
// ["tv"; "tV"; "Tv"; "TV"; "uv"; "uV"; "Uv"; "UV"]

或者,我们可以使用内置的CompareTo函数,它会产生相同的结果:

代码语言:javascript
运行
AI代码解释
复制
strings |> List.sortWith (fun x y -> x.CompareTo(y))
// ["tv"; "tV"; "Tv"; "TV"; "uv"; "uV"; "Uv"; "UV"] 

这个故事的寓意:如果你关心排序,总是指定要使用的具体比较!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30999018

复制
相关文章
java中&&和&的区别
&&和&都是用于“与”运算,不同的是&&是逻辑与,&是按位与,所谓逻辑与指的是两个判断条件在都为true时结果为true,举个生活中例子,比如英语成绩大于90与数学成绩大于90才是好学生一样,代码如下:
全栈程序员站长
2021/07/07
7190
Java中&和&&的区别
首先给i赋值为0,如果i大于10,并且i++等于1,则输出“错误”和i的值。否则输出“正确”和i的值。分别用&和&&运行,观察运行结果的不同。
算法与编程之美
2022/10/28
4690
Java中&和&&的区别
java中 +=和+的区别[通俗易懂]
java中+=的意义包含两部分,一是”+”,就是通常所说的直接相加,二是改变结果的类型,将计算结果的类型转换为”+=符号左边的类型。
全栈程序员站长
2022/09/08
7630
java中&和&&的区别和联系
当: str != null 的时候,接下来才会去执行: !"".equals(str)
Hongten
2018/09/13
1K0
Java中==和equals的区别
在Java中,equals是在object类中的方法,在object中equals是用来看看两个参数是否引用的是同一个对象,而 == 可用于判断两个对象的地址是否相等,那么equals和 == 有什么区别?
算法与编程之美
2023/08/22
1620
Java中==和equals的区别
java中 this和super的区别
this表示当前调用方法的对象的引用: (谁调用这个方法,谁就是这个对象,这个this就是它的引用) 比如: <pre name="code" class="java">public class This_Demo{ String name; public void setName(String name) { this.name = name;// 前一个name是 本类的成员属性: name;后一个name是setName中的参数。 } public s
MickyInvQ
2020/09/27
2870
Java中==和equals的区别
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean 
JaneYork
2023/10/11
1480
Java中==和equals的区别
java中“==”和equal区别
8个月以后就要正式找工作啦,我觉得现在是时候花时间好好深入研究一下以前比较混肴的知识。这就当作是自我成长的第一步!
哲洛不闹
2018/09/19
5510
java中“==”和equal区别
JAVA中&&和&、||和|的区别?「建议收藏」
&&逻辑与 也叫做短路与 因为只要当前项为假,它就不往后判断了,直接认为表达式为假
全栈程序员站长
2022/09/08
4990
Java中this和super的区别和应用
Java中this和super的区别和应用 1 /* 2 问题是: 3 1.我不仅仅要输出局部范围的变量num,还要输出本类成员范围的变量num。怎么办呢? 4 2.我还想要输出父类成员范围的变量num。怎么办呢? 5 如果有一个东西和this相似,但是可以直接访问父类的数据就好了。 6 恭喜你,这个关键字是存在的:super。 7 8 this和super的区别? 9
黑泽君
2018/10/11
9200
java中的stringbuffer是什么_java中&和&&的区别
JAVA提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。
全栈程序员站长
2022/11/08
9520
Java中sleep和wait的区别
2、sleep方法使当前线程暂停执行指定的时间,让出cpu给其他线程,但是它的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。在调用sleep方法后,线程不会释放对象锁;
编程大道
2019/08/26
3.3K0
java中error和exception的区别
Error类和Exception类的父类都是throwable类,他们的区别是: Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。
老马的编程之旅
2022/06/22
4320
java中重载和重写的区别
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
全栈程序员站长
2022/09/08
6980
java中Comparable和Comparator的区别
java.lang.Comparable和java.util.Comparator是两个容易混淆的接口,两者都带有比较的意思,那么两个接口到底有什么区别,分别在什么情况下使用呢?
子润先生
2021/06/22
3300
Java中equals和hashcode的区别
== 运算符用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能使用 “==” 运算符。
程序员Leo
2023/08/02
1930
java中Runnable和Callable的区别
在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是java1.5添加进来的一个增强版本。
程序那些事
2020/07/08
8050
java中堆和栈的区别
堆和栈都是Java用来在RAM中存放数据的地方。 堆 (1)Java的堆是一个运行时数据区,类的对象从堆中分配空间。这些对象通过new等指令建立,通过垃圾回收器来销毁。 (2)堆的优势是可以动态地分配内存空间,需要多少内存空间不必事先告诉编译器,因为它是在运行时动态分配的。但缺点是,由于需要在运行时动态分配内存,所以存取速度较慢。  栈 (1)栈中主要存放一些基本数据类型的变量(byte,short,int,long,float,double,boolean,char)和对象的引用。 (2)栈的优势是,存取
nnngu
2018/03/15
8950
Java中int和Integer的区别
Java是面向对象的编程语言,一切都是对象,但是为了编程的方便还是引入了基本数据类型,为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换,对应如下:
joshua317
2021/03/16
8040
Java中executeUpdate和executeQuery的区别
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/01
2510

相似问题

Java中=+和+=的区别?

20

java中"this“和不带"this”的区别

50

+=和=+在java中的区别?

44

java脚本中"==“和"===”的区别

13

Java中"==“和”相等“的区别

42
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档