我有一组记录:
type Person =
{
Name : string
Age : int
}
let oldPeople =
set [ { Name = "The Doctor"; Age = 1500 };
{ Name = "Yoda"; Age = 900 } ]
与上面的硬编码示例不同,数据集实际上来自数据源(我几乎无法控制)。现在我需要从另一个数据源中减去一组数据。一般来说,第二个来源中的数据匹配,但偶尔会有资本化的差异:
let peopleWhoAreConfusedAboutTheirAge =
set [ { Name = "THE DOCTOR"; Age = 1500 } ]
当我尝试从第一个集合中减去第二个集合时,它会失败,因为字符串比较区分大小写:
let peopleWhoKnowHowOldTheyAre =
oldPeople - peopleWhoAreConfusedAboutTheirAge
val peopleWhoKnowHowOldTheyAre : Set<Person> =
set [{Name = "The Doctor";
Age = 1500;}; {Name = "Yoda";
Age = 900;}]
有没有办法对Name
记录的People
字段执行不区分大小写的比较?
答案 0 :(得分:2)
这是我到目前为止所实现的,尽管可能有更好的方法。
我的解决方案是覆盖Equals
记录上的People
函数,以便执行不区分大小写的比较。设置减法使用Equals
函数来确定两个记录是否彼此匹配。通过覆盖Equals
,我被迫(通过警告和错误)覆盖GetHashCode
并实施IComparable
(以及设置CustomEquality
和CustomComparison
属性) :
[<CustomEquality; CustomComparison>]
type Person =
{
Name : string
Age : int
}
member private this._internalId =
this.Name.ToLower() + this.Age.ToString()
interface System.IComparable with
member this.CompareTo obj =
let other : Person = downcast obj
this._internalId.CompareTo( other._internalId )
override this.Equals( other ) =
match other with
| :? Person as other ->
System.String.Compare( this._internalId, other._internalId ) = 0
| _ -> false
override this.GetHashCode() =
this._internalId.GetHashCode()
然而,这似乎可以解决问题:
let oldPeople =
set [ { Name = "The Doctor"; Age = 1500 };
{ Name = "Yoda"; Age = 900 } ]
let peopleWhoAreConfusedAboutTheirAge =
set [ { Name = "THE DOCTOR"; Age = 1500 } ]
let peopleWhoKnowHowOldTheyAre =
oldPeople - peopleWhoAreConfusedAboutTheirAge
val peopleWhoKnowHowOldTheyAre : Set<Person> = set [{Name = "Yoda";
Age = 900;}]
如果你知道一个更好的解决方案(涉及更少的代码),请发布它而不是评论这个答案。我很乐意接受一个不那么冗长,尴尬的解决方案。
答案 1 :(得分:2)
这是另一种方法:
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