Sorting F“对Excel进行排序的函数”;变体“;在Excel Dna中
当尝试使用以下函数对1d变量数组(这里的“变量”是指所有Excel类型,例如bool、double(和date)、string、各种错误…)进行排序时:Sorting F“对Excel进行排序的函数”;变体“;在Excel Dna中,sorting,f#,excel-dna,Sorting,F#,Excel Dna,当尝试使用以下函数对1d变量数组(这里的“变量”是指所有Excel类型,例如bool、double(和date)、string、各种错误…)进行排序时: [<ExcelFunction(Category="test", Description="sort variants.")>] let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
[<ExcelFunction(Category="test", Description="sort variants.")>]
let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
arr
|> Array.sort
(我不确定是否需要NIL,但这并没有什么坏处。另外,在我的实际代码中,我添加了DateTime的DT
实例,因为我需要区分日期和双精度)
let弓形变异体(x:obj):XLVariant=
将x与
| :? 双倍于d->d
| :? 字符串为s->s
| :? bool as b->b
|->NIL“未知匹配”
let of XLVariant(x:XLVariant):obj=
将x与
|D->D框
|S->方框S
|B->B框
|无->框ExcelError.ExcelErrorRef
[]
let sort_变量([]arr:obj[]):obj[]=
啊
|>Array.map弓形变量
|>数组.sort
|>数组.xlvariant的映射
(为了简单起见,我错过了错误类型,但想法是一样的)这对我来说似乎更明确一些,因为它只适用于CLR类型系统:
// Compare objects in the way Excel would
let xlCompare (v1 : obj) (v2 : obj) =
match (v1, v2) with
| (:? double as d1), (:? double as d2) -> d1.CompareTo(d2)
| (:? double), _ -> -1
| _, (:? double) -> 1
| (:? string as s1), (:? string as s2) -> s1.CompareTo(s2)
| (:? string), _ -> -1
| _, (:? string) -> 1
| (:? bool as b1), (:? bool as b2) -> b1.CompareTo(b2)
| (:? bool), _ -> -1
| _, (:? bool) -> 1
| _ -> 2
[<ExcelFunction(Category="test", Description="sort variants.")>]
let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
Array.sortWith xlCompare arr
//以Excel的方式比较对象
让我们比较一下(v1:obj)(v2:obj)=
将(v1,v2)与
|(:?双倍于d1),(:?双倍于d2)->d1。与(d2)相比
|(:?双),->-1
|_u,(:?双)->1
|(:?字符串作为s1),(:?字符串作为s2)->s1.CompareTo(s2)
|(:?字符串),->-1
|_u,(:?字符串)->1
|(:?布尔值为b1),(:?布尔值为b2)->b1.与(b2)相比
|(:?bool),->-1
|_u,(:?bool)->1
| _ -> 2
[]
let sort_变量([]arr:obj[]):obj[]=
Array.sortWith xlCompare arr
我对Excel Dna不太了解,无法写出正确的答案,但您的DU解决方案在我看来很好:通过对DU案例进行排序,使其与Excel的自然排序功能相匹配(我不知道),您可以从没有那么多代码中获得很多好处。我想说你写的是一个很好的方法,我想不出改进的方法。因为类型信息已经是obj
值的一部分,如果你只实现IComparer
,并明确所需的顺序,可能会更简单。
let toXLVariant (x : obj) : XLVariant =
match x with
| :? double as d -> D d
| :? string as s -> S s
| :? bool as b -> B b
| _ -> NIL "unknown match"
let ofXLVariant (x : XLVariant) : obj =
match x with
| D d -> box d
| S s -> box s
| B b -> box b
| NIL _ -> box ExcelError.ExcelErrorRef
[<ExcelFunction(Category="test", Description="sort variants.")>]
let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
arr
|> Array.map toXLVariant
|> Array.sort
|> Array.map ofXLVariant
// Compare objects in the way Excel would
let xlCompare (v1 : obj) (v2 : obj) =
match (v1, v2) with
| (:? double as d1), (:? double as d2) -> d1.CompareTo(d2)
| (:? double), _ -> -1
| _, (:? double) -> 1
| (:? string as s1), (:? string as s2) -> s1.CompareTo(s2)
| (:? string), _ -> -1
| _, (:? string) -> 1
| (:? bool as b1), (:? bool as b2) -> b1.CompareTo(b2)
| (:? bool), _ -> -1
| _, (:? bool) -> 1
| _ -> 2
[<ExcelFunction(Category="test", Description="sort variants.")>]
let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
Array.sortWith xlCompare arr