F sharp 添加列表
F sharp adding lists
如何将obj列表转换为int类型。我正在尝试使用下面的地图函数添加两个列表,但它不适用于 obj 列表。
let query f=
seq{
let cmd = new OleDbCommand( "SELECT * FROM F" );
let conn = new OleDbConnection( @"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=D:\Users\df\Documents\Vfolio.accdb;
Persist Security Info=False;" )
conn.Open()
let DAdapt = new OleDbDataAdapter("SELECT * FROM F",conn)
let DTab = new DataSet()
let i= DAdapt.Fill(DTab)
let rowCol = DTab.Tables.[0].Rows
let rowCount = rowCol.Count
for i in 0 .. (rowCount - 1) do
yield f (rowCol.[i])
}
let u= query(fun row -> row.[0])
let a= List.ofSeq u
let v=query(fun row -> row.[1])
let b= List.ofSeq v
let c = List.map2 (fun x y-> x + y) a b
错误消息:类型 'obj' 不支持运算符 '+'
因为 row.[i]
returns 输入 obj
,你的 u
和 v
变成 seq<obj>
,因此你的 a
和 b
成为类型 List<obj>
,因此 x
和 y
被推断为类型 obj
,当然,你不能添加两个 obj
s,这正是编译器告诉你的。
如果您确定 row.[0]
和 row.[1]
是某种数字,您应该应用适当的转换,例如:
let u= query(fun row -> row.[0] :?> int)
let a= List.ofSeq u
let v=query(fun row -> row.[1] :?> int)
let b= List.ofSeq v
let c = List.map2 (fun x y-> x + y) a b
您也可以在其他地方应用此转换,具体取决于您的品味和要求,例如:
let c = List.map2 (fun x y-> (x :?> int) + (y :?> int)) a b
或:
let a= u |> Seq.cast<int> |> List.ofSeq
let b= v |> Seq.cast<int> |> List.ofSeq
但我最喜欢第一个示例,因为它在已知的最早时间点应用强制转换,并产生最少的额外代码。
但要注意:如果 row.[0]
在运行时结果不是 int
,您将得到一个 InvalidCastException
.
P.S. 在您的 List.map2
调用中,您可以直接指定 (+)
而不是将其包装在额外的 lambda 中:
List.map2 (+) a b
P.P.S另外,你的List.ofSeq
电话似乎很浪费,因为Seq
也有一个map2
:
let u = query(fun row -> row.[0] :?> int)
let v = query(fun row -> row.[1] :?> int)
let c = Seq.map2 (+) u v |> List.ofSeq
P.P.P.S 此外,您是否注意到对 query
的两次调用中的每一次都会生成自己的数据库连接、命令、适配器和数据集?您是有意这样做还是只想建立一个连接然后从结果中获取不同的列?如果是这样,您应该只调用 query
一次:
let c = query( fun row -> (row.[0] :?> int) + (row.[1] :?> int) ) |> List.ofSeq
如何将obj列表转换为int类型。我正在尝试使用下面的地图函数添加两个列表,但它不适用于 obj 列表。
let query f=
seq{
let cmd = new OleDbCommand( "SELECT * FROM F" );
let conn = new OleDbConnection( @"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=D:\Users\df\Documents\Vfolio.accdb;
Persist Security Info=False;" )
conn.Open()
let DAdapt = new OleDbDataAdapter("SELECT * FROM F",conn)
let DTab = new DataSet()
let i= DAdapt.Fill(DTab)
let rowCol = DTab.Tables.[0].Rows
let rowCount = rowCol.Count
for i in 0 .. (rowCount - 1) do
yield f (rowCol.[i])
}
let u= query(fun row -> row.[0])
let a= List.ofSeq u
let v=query(fun row -> row.[1])
let b= List.ofSeq v
let c = List.map2 (fun x y-> x + y) a b
错误消息:类型 'obj' 不支持运算符 '+'
因为 row.[i]
returns 输入 obj
,你的 u
和 v
变成 seq<obj>
,因此你的 a
和 b
成为类型 List<obj>
,因此 x
和 y
被推断为类型 obj
,当然,你不能添加两个 obj
s,这正是编译器告诉你的。
如果您确定 row.[0]
和 row.[1]
是某种数字,您应该应用适当的转换,例如:
let u= query(fun row -> row.[0] :?> int)
let a= List.ofSeq u
let v=query(fun row -> row.[1] :?> int)
let b= List.ofSeq v
let c = List.map2 (fun x y-> x + y) a b
您也可以在其他地方应用此转换,具体取决于您的品味和要求,例如:
let c = List.map2 (fun x y-> (x :?> int) + (y :?> int)) a b
或:
let a= u |> Seq.cast<int> |> List.ofSeq
let b= v |> Seq.cast<int> |> List.ofSeq
但我最喜欢第一个示例,因为它在已知的最早时间点应用强制转换,并产生最少的额外代码。
但要注意:如果 row.[0]
在运行时结果不是 int
,您将得到一个 InvalidCastException
.
P.S. 在您的 List.map2
调用中,您可以直接指定 (+)
而不是将其包装在额外的 lambda 中:
List.map2 (+) a b
P.P.S另外,你的List.ofSeq
电话似乎很浪费,因为Seq
也有一个map2
:
let u = query(fun row -> row.[0] :?> int)
let v = query(fun row -> row.[1] :?> int)
let c = Seq.map2 (+) u v |> List.ofSeq
P.P.P.S 此外,您是否注意到对 query
的两次调用中的每一次都会生成自己的数据库连接、命令、适配器和数据集?您是有意这样做还是只想建立一个连接然后从结果中获取不同的列?如果是这样,您应该只调用 query
一次:
let c = query( fun row -> (row.[0] :?> int) + (row.[1] :?> int) ) |> List.ofSeq