F # последовательности - как вернуть несколько строк - PullRequest
1 голос
/ 14 февраля 2011
let x = [for p in db.ParamsActXes do
                                            if p.NumGroupPar = grp then
                                                yield p.Num, p.Name]

Вот моя последовательность, но проблема в том, что она возвращает список кортежей, я не могу получить доступ к одному элементу кортежа, как

let str = "hello" + x.[1]

, и это проблема.* Как я могу реализовать этого функционера?

Ответы [ 4 ]

4 голосов
/ 14 февраля 2011

Чтобы получить доступ ко второму элементу 2-кортежа, вы можете использовать snd или сопоставление с образцом. Так что, если tup является 2-кортежем, где второй элемент tup является строкой, вы можете сделать:

let str = "hello" + snd tup

или

let (a,b) = tup
let st = "hello" + b

Обратите внимание, что snd работает только с 2-мя кортежами, а не с более чем двумя элементами.

3 голосов
/ 14 февраля 2011

Чтобы дать вам еще одно альтернативное решение, вы можете просто создать отфильтрованную последовательность, содержащую значения исходного типа, написав yield p:

let x = [ for p in db.ParamsActXes do
            if p.NumGroupPar = grp then
              yield p ]

, а затем просто получить доступ к нужному свойству:

let str = "hello" + x.[1].Name

Вероятно, это хорошая идея, если вы возвращаете только несколько свойств значения p.Единственная причина получения кортежей состоит в том, чтобы скрыть что-то от остальной части кода или создать последовательность, которая соответствует некоторой функции, которую вы используете позже.

(Кроме того, я бы не стал индексировать списки, используя x.[i], потому чтоэто неэффективно, но, возможно, это просто для иллюстрации в опубликованном образце. Используйте массив, если вам нужен доступ на основе индекса, заключив выражение последовательности в [| ... |])

2 голосов
/ 14 февраля 2011

Просто чтобы добавить еще одну возможность, если вы используете сборку .NET 4.0 для F # 2.0, вы можете выполнить приведение во время выполнения из кортежа F # в .NET 4.0 System.Tuple и затем использовать свойства ItemX кортежей .NET 4.0 для доступа к нужному элементу кортежа

let x = (1, 1.2, "hello")
let y = ((box x) :?> System.Tuple<int, float, string>);;
y.Item3 //returns "hello"

Однако я бы никогда не использовал это, вместо этого выбрав извлечение совпадения с образцом. (также я читал места, где компилятор F # не всегда может представлять свои кортежи в виде кортежей .NET 4.0, поэтому может быть вероятность, что приведение завершится неудачно).

Читая ваши комментарии в некоторых других ответах, я не уверен, почему решение для сопоставления с образцом не работает для вас. Возможно, вы хотите получить доступ к элементу кортежа в определенном месте выражения? Если это так, предыдущий, безусловно, будет работать:

let str = "hello" + ((box x.[1]) :?> System.Tuple<int,string>).Item2 //though might as well use snd and fst for length 2 F# tuples

но вы можете достичь тех же целей, используя метод извлечения совпадений по шаблону (опять же, если предположить, что это даже то, что вам нужно):

let str = "hello" + (let (_,name) = x.[1] in name)
1 голос
/ 14 февраля 2011

вы можете получить доступ к отдельному кортежу из списка кортежей, используя List.nth.

let first, second = List.nth x 0

first и second представляют отдельный элемент кортежа.

...