F резкое добавление списков

Как конвертировать список obj в тип int Я пытаюсь добавить два списка, используя функцию карты ниже, но она не работает в списках объектов.

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' не поддерживает оператор '+'

1 ответ

Решение

Так как row.[i] возвращает тип obj, ваш u а также v становиться seq<obj>и, таким образом, ваш a а также b стать типом List<obj>, и поэтому x а также y Предполагается, чтобы иметь тип objи, конечно, вы не можете добавить два objs, это именно то, что говорит вам компилятор.

Если вы уверены, что 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,

PS по вашему List.map2 позвоните, вы можете указать (+) непосредственно вместо того, чтобы обернуть это в дополнительную лямбду:

List.map2 (+) a b

PPS Кроме того, кажется, что ваш 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

PPPS Кроме того, вы заметили, что каждый из двух звонков query генерирует свое собственное соединение с БД, команду, адаптер и набор данных? Вы намеревались это сделать или имели в виду только одно соединение, а затем извлекать разные столбцы из результата? Если это так, вы должны только позвонить query один раз:

let c = query( fun row -> (row.[0] :?> int) + (row.[1] :?> int) ) |> List.ofSeq
Другие вопросы по тегам