Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 使用不区分大小写的比较从集合中减去记录_F#_Record_String Comparison - Fatal编程技术网

F# 使用不区分大小写的比较从集合中减去记录

F# 使用不区分大小写的比较从集合中减去记录,f#,record,string-comparison,F#,Record,String Comparison,我有一套记录: 输入人物= { 名称:string 年龄:整数 } 让老人= 设置[{Name=“The Doctor”;年龄=1500}; {Name=“Yoda”;年龄=900}] 与上面的硬编码示例不同,数据集实际上来自一个数据源(对此我几乎没有控制权)。现在我需要从另一个数据源中减去一组数据。一般来说,第二个源中的数据是匹配的,但有时在资本化方面存在差异: 让困惑的人放弃他们的年龄= set[{Name=“THE DOCTOR”;Age=1500}] 当我尝试从第一个集合中减去第二个

我有一套记录:

输入人物=
{
名称:string
年龄:整数
}
让老人=
设置[{Name=“The Doctor”;年龄=1500};
{Name=“Yoda”;年龄=900}]
与上面的硬编码示例不同,数据集实际上来自一个数据源(对此我几乎没有控制权)。现在我需要从另一个数据源中减去一组数据。一般来说,第二个源中的数据是匹配的,但有时在资本化方面存在差异:

让困惑的人放弃他们的年龄=
set[{Name=“THE DOCTOR”;Age=1500}]
当我尝试从第一个集合中减去第二个集合时,它失败了,因为字符串比较区分大小写:

让那些知道自己年龄的人=
老年人-对他们的年龄感到困惑的人
val知道自己年龄的人:Set=
设置[{Name=“医生”;
年龄=1500;};{Name=“Yoda”;
年龄=900;}]

有没有一种方法可以对
人员
记录的
姓名
字段执行不区分大小写的比较?

这就是我迄今为止实现的方法,尽管可能有更好的方法

我的解决方案是重写
People
记录上的
Equals
函数,以便执行不区分大小写的比较。Set减法使用
Equals
函数确定两条记录是否相互匹配。通过覆盖
Equals
,我被迫(通过警告和错误)覆盖
GetHashCode
,并实现
IComparable
(以及设置
CustomEquality
CustomComparison
属性):

[]
类型人=
{
名称:string
年龄:整数
}
此为成员私有。\u内部ID=
this.Name.ToLower()+this.Age.ToString()
接口系统.i可与
请将此成员与obj进行比较=
让他人:人=沮丧的对象
此.\u internalId.CompareTo(其他.\u internalId)
覆盖此。等于(其他)=
相配
| :? 作为其他人的人->
System.String.Compare(this.\u internalId,other.\u internalId)=0
|_u->false
重写这个。GetHashCode()=
这是。_internalId.GetHashCode()
然而,这似乎起到了作用:

让老年人=
设置[{Name=“The Doctor”;年龄=1500};
{Name=“Yoda”;年龄=900}]
让困惑的人放弃他们的年龄=
set[{Name=“THE DOCTOR”;Age=1500}]
让那些知道自己年龄的人=
老年人-对他们的年龄感到困惑的人
val知道自己的年龄的人:Set=Set[{Name=“Yoda”;
年龄=900;}]

如果你知道一个更好的解决方案(涉及更少的代码),请发表它,而不是评论这个答案。我很乐意接受一个不那么冗长、笨拙的解决方案。

这是我迄今为止实现的,尽管可能有更好的方法

我的解决方案是重写
People
记录上的
Equals
函数,以便执行不区分大小写的比较。Set减法使用
Equals
函数确定两条记录是否相互匹配。通过覆盖
Equals
,我被迫(通过警告和错误)覆盖
GetHashCode
,并实现
IComparable
(以及设置
CustomEquality
CustomComparison
属性):

[]
类型人=
{
名称:string
年龄:整数
}
此为成员私有。\u内部ID=
this.Name.ToLower()+this.Age.ToString()
接口系统.i可与
请将此成员与obj进行比较=
让他人:人=沮丧的对象
此.\u internalId.CompareTo(其他.\u internalId)
覆盖此。等于(其他)=
相配
| :? 作为其他人的人->
System.String.Compare(this.\u internalId,other.\u internalId)=0
|_u->false
重写这个。GetHashCode()=
这是。_internalId.GetHashCode()
然而,这似乎起到了作用:

让老年人=
设置[{Name=“The Doctor”;年龄=1500};
{Name=“Yoda”;年龄=900}]
让困惑的人放弃他们的年龄=
set[{Name=“THE DOCTOR”;Age=1500}]
让那些知道自己年龄的人=
老年人-对他们的年龄感到困惑的人
val知道自己的年龄的人:Set=Set[{Name=“Yoda”;
年龄=900;}]

如果你知道一个更好的解决方案(涉及更少的代码),请发表它,而不是评论这个答案。我很乐意接受一个不那么冗长、笨拙的解决方案。

这里是另一种方法:

type Name(value) =
  member val Value = value
  override this.Equals(that) =
    match that with 
    | :? Name as name -> StringComparer.CurrentCultureIgnoreCase.Equals(this.Value, name.Value)
    | _ -> false
  override this.GetHashCode() =
    StringComparer.CurrentCultureIgnoreCase.GetHashCode(this.Value)

type Person =
  {
    Name: Name
    Age: int
  }

{Name=Name("John"); Age=21} = {Name=Name("john"); Age=21} //true

以下是另一种方法:

type Name(value) =
  member val Value = value
  override this.Equals(that) =
    match that with 
    | :? Name as name -> StringComparer.CurrentCultureIgnoreCase.Equals(this.Value, name.Value)
    | _ -> false
  override this.GetHashCode() =
    StringComparer.CurrentCultureIgnoreCase.GetHashCode(this.Value)

type Person =
  {
    Name: Name
    Age: int
  }

{Name=Name("John"); Age=21} = {Name=Name("john"); Age=21} //true

只需添加
IComparable
实现,这就是OP想要的。我曾考虑过这种方法,但它确实使我使用Person记录的代码更加冗长。如果可能的话,我喜欢包含冗长的内容。如果您不想放弃F#records默认提供的结构相等/结构比较,那么您需要将字段或整个记录包装在一个类或联合中,在该类或联合中执行自定义相等/自定义比较。请参阅,例如,只需添加
IComparable
实现,这正是OP想要的。我曾考虑过这种方法,但它确实会使我使用Person记录的代码更加冗长。如果可能的话,我喜欢包含冗长的内容。如果您不想放弃F#records默认提供的结构相等/结构比较,那么您需要将字段或整个记录包装在一个类或联合中,在该类或联合中执行自定义相等/自定义比较。见例。