brinch
brinch

Reputation: 2614

How to Select by LINQ into anonymous type in F#

I have this code snippet, which creates an array of anonymously typed elements with properties Name and FirstLetter:

string[] arr = { "Dennis", "Leo", "Paul" };

var myRes = arr.Select(a => new { Name = a, FirstLetter = a[0] });

I would like to do the same in F#. I tried:

let names = [| "Dennis"; "Leo"; "Paul" |]

let myRes = names.Select(fun a -> {Name = a; FirstLetter = a[0]} )

But this doesn't compile. It says:

The record label 'Name' is not defined.

How can I get this line to work in F#?

Upvotes: 7

Views: 2606

Answers (2)

jpierson
jpierson

Reputation: 17364

Your initial attempts would work more intuitively as of F# 4.6. Testing a similar example using .NET Core SDK 3.0.100-preview4 I was able to prove this out using the new Anonymous Record feature.

let names = [| "Dennis"; "Leo"; "Paul" |]

let myRes = names.Select(fun a -> {| Name = a; FirstLetter = a.[0] |})

Notice the use of the | character on the insides of the curly braces. This is what now distinguishes regular records from anonymous records in F#. Also notice that when accessing the first character of a string in F# that the . method accessor operator must be used to access the indexer just like when accessing other methods.

Upvotes: 4

myroman
myroman

Reputation: 562

As in comments, F# doesn't support anonymous type. So if you want to project your sequence into another sequence, create a record, which is essentially a tuple with named fields.

type p = { 
  Name:string;
  FirstLetter: char 
}

let names = [| "Dennis"; "Leo"; "Paul" |]
let myRes = names.Select(fun a -> {Name = a; FirstLetter = a.[0]} )   

Upvotes: 7

Related Questions