2016-07-27 5 views
6

Каков хороший и эффективный способ сделать такой бросок?Значения seq.cast tuple от obj до строки

seq { yield (box "key", box "val") } 
|> Seq.cast<string*string> 

Так как это выглядит очень некрасиво:

seq { yield (box "key", box "val") } 
|> Seq.map (fun (k,v) -> k.ToString(), v.ToString()) 

Как это:

seq { yield (box "key", box "val") } 
|> Seq.map (fun (k,v) -> unbox<string>(k), unbox<string>(v)) 

Есть ли способ "распаковывать" кортеж в другой кортеж?

+1

просто скомпрометируйте его в функции unBoxString (k, v). И вы можете вызвать .ToString() непосредственно на объект в штучной упаковке. – s952163

+0

Благодарим вас за предложение, но я не могу называть 'ToString()' на коробчатом кортеже, так как получаю строковое представление. И вместо этого я хочу получить кортеж из двух строк. – derwasp

+0

Да, конечно. Я имел в виду это, как в ответе Марка, где используется строковая функция. Вам нужно будет вызвать его на каждый объект в штучной упаковке, который вы уже делаете. Я думаю, когда он чувствует себя «уродливым», легко написать один лайнер. Наличие многих вспомогательных функций является идиоматическим. Ответ является хорошим примером этого. – s952163

ответ

8

Вы могли бы написать его немного лучше, как:

seq { yield (box "key", box "val") } 
|> Seq.map (fun (k, v) -> string k, string v) 

Представьте себе, однако, что у вас есть Tuple2 модуль:

module Tuple2 = 
    // ... other functions ... 

    let mapBoth f g (x, y) = f x, g y 

    // ... other functions ... 

С такой mapBoth функции, вы можете написать свой бросок, как:

seq { yield (box "key", box "val") } |> Seq.map (Tuple2.mapBoth string string) 

Нет Tuple2 в FSharp.Core, но я часто определяю один в своих проектах, содержащий различные удобные однострочные линии, подобные приведенным выше.

+0

'string k, string v' уже выглядит немного лучше. Поскольку в моем случае это всего лишь сценарий сборки, я не думаю, что я бы создал для этого модуль, я просто перейду с первым предложенным вариантом. – derwasp

Смежные вопросы