Home > Software design >  Flatten a sequence of sequences into a single sequence (List<string> from List<Object> c
Flatten a sequence of sequences into a single sequence (List<string> from List<Object> c

Time:09-01

I'm trying to extract some Lists of strings into a single List. First I have this class

public class Client
{
  public string Name { get; set; }

  public List<string> ApiScopes { get; set; }
}

Thus I'm getting my response as a List<Client> and my intention is to take all Client's Scopes into a single List without Looping I've tried this by LINQ:

        var x = clients.Select(c=> c.AllowedScopes.Select(x => x).ToList()).ToList();

this returns a List<List<string>>, and I just want to get all this into one Distinct list of strings.

CodePudding user response:

It sounds like you want SelectMany (which flattens a sequence of sequences into a single sequence), with Distinct as well if you need a list with each scope only appearing once even if it's present for multiple clients:

var scopes = clients.SelectMany(c => c.ApiScopes).Distinct().ToList();

This assumes that Client.ApiScopes is never null. If it might be null, you need a little bit more work:

var scopes = clients
    .SelectMany(c => ((IEnumerable<string>) c.ApiScopes) ?? Enumerable.Empty<string>())
    .Distinct()
    .ToList();

CodePudding user response:

You can use SelectMany to flatten results :

var scopes=clients.SelectMany(client=>client.ApiScopes)
                  .Distinct()
                  .ToList();

This is equivalent to :

var scopes= ( from client in clients
              from scope in client.ApiScopes
              select scope
            )
            .Distinct()
            .ToList();
  • Related