Wilson
Wilson

Reputation: 8768

Get certain item from each Tuple from List

What is the correct way to go about creating a list of, say, the first item of each Tuple in a List of Tuples?

If I have a List<Tuple<string,string>>, how would I get a List<string> of the first string in each Tuple?

Upvotes: 18

Views: 21377

Answers (4)

Declan Taylor
Declan Taylor

Reputation: 405

Generialised Variant: for selecting a particular item where the collection's tuple's length is unknown i.e 2,3,4 ...:

    static IEnumerable TupleListSelectQuery<T>(IEnumerable<T> lst, int index) where T : IStructuralEquatable, IStructuralComparable, IComparable
    {
        return lst.Select(t => typeof(T).GetProperty("Item" + Convert.ToString(itemNumber)).GetValue(t)).ToList();
    }

where index's value corresponds to the way tuples are enumerated i.e 1,2,3 ... (not 0,1,2...).

Upvotes: 0

KeithS
KeithS

Reputation: 71565

A little Linq will do the trick:

var myStringList = myTupleList.Select(t=>t.Item1).ToList();

As an explanation, since Tim posted pretty much the same answer, Select() creates a 1:1 "projection"; it takes each input element of the Enumerable, and for each of them it evaluates the lambda expression and returns the result as an element of a new Enumerable having the same number of elements. ToList() will then spin through the Enumerable produced by Select(), and add each element one at a time to a new List<T> instance.

Tim has a good point on the memory-efficiency; ToList() will create a list and add the elements one at a time, which will cause the List to keep resizing its underlying array, doubling it each time to ensure it has the proper capacity. For a big list, that could cause OutOfMemoryExceptions, and it will cause the CLR to allocate more memory than necessary to the List unless the number of elements happens to be a power of 2.

Upvotes: 24

Tim Schmelter
Tim Schmelter

Reputation: 460058

List<string> list = tuples.Select(t => t.Item1).ToList();

or, potentially less memory expensive:

List<string> list = new List<String>(tuples.Count);
list.AddRange(tuples.Select(t => t.Item1));

because it avoids the doubling algorithm of List.Add in ToList.

Upvotes: 6

yoozer8
yoozer8

Reputation: 7489

If you have a List<Tuple<string, string>> listoftuples, you can use the List's implementation of the Select method to take the first string from each Tuple.

It would look like this:

List<string> firstelements = listoftuples.Select(t => t.Item1).ToList();

Upvotes: 0

Related Questions