Каков правильный способ создания списка, скажем, первого элемента каждого Tuple
в List
из Tuples
?
Если у меня есть List<Tuple<string,string>>
, как бы я получил List<string>
первой строки в каждом Tuple
?
Каков правильный способ создания списка, скажем, первого элемента каждого Tuple
в List
из Tuples
?
Если у меня есть List<Tuple<string,string>>
, как бы я получил List<string>
первой строки в каждом Tuple
?
Маленький Linq сделает трюк:
var myStringList = myTupleList.Select(t=>t.Item1).ToList();
В качестве объяснения, поскольку Тим опубликовал почти такой же ответ, Select() создает 1:1 "проекцию"; он берет каждый элемент ввода Enumerable, и для каждого из них он вычисляет лямбда-выражение и возвращает результат как элемент нового Enumerable, имеющего такое же количество элементов. Затем ToList() будет прокручиваться через Enumerable, созданный Select(), и добавлять каждый элемент по одному к новому экземпляру List<T>
.
Тим имеет хорошую точку в эффективности памяти; ToList() создаст список и добавит элементы по одному, что приведет к тому, что List сохранит размер своего базового массива, удваивая его каждый раз, чтобы обеспечить его надлежащую емкость. Для большого списка, который может вызвать OutOfMemoryExceptions, и это приведет к тому, что CLR будет выделять больше памяти, чем это необходимо для Списка, если количество элементов не будет равным 2.
List<string> list = tuples.Select(t => t.Item1).ToList();
или, что потенциально менее дорого стоит:
List<string> list = new List<String>(tuples.Count);
list.AddRange(tuples.Select(t => t.Item1));
поскольку он избегает алгоритма удвоения List.Add
в ToList
.
Если у вас есть List<Tuple<string, string>> listoftuples
, вы можете использовать реализацию List метода Select, чтобы перенести первую строку из каждого Tuple.
Это будет выглядеть так:
List<string> firstelements = listoftuples.Select(t => t.Item1).ToList();
решение для выбора конкретного элемента, где длина набора записей неизвестна, т.е. 2,3,4 и т.д. (он является общим):
static IEnumerable TupleListSelectQuery<T>(IEnumerable<T> lst, int itemNumber) where T : IStructuralEquatable, IStructuralComparable, IComparable
{
return lst.Select(t => typeof(T).GetProperty("Item" + Convert.ToString(itemNumber)).GetValue(t)).ToList();
}
как расширение:
public static class TupleExtension
{
public static IEnumerable SelectByPosition<T>(this IEnumerable<T> lst, int itemNumber) where T : IStructuralEquatable, IStructuralComparable, IComparable
{
return lst.Select(t => typeof(T).GetProperty("Item" + Convert.ToString(itemNumber)).GetValue(t)).ToList();
}
}
где 'itemNumber' соответствует способу перечисления кортежей i.e 1,2,3 и т.д., а не 0,1,2 и т.д.