#c# #list #linq #collections
Вопрос:
У меня есть список типа class abc
public class abc
{
public int count;
public string country;
}
Список может иметь такие значения, как
Количество: 1 — страна: США
Количество: 2 — страна: США
Количество: 3 — страна: IND
Количество: 4 — страна: Великобритания
Количество: 5 — страна: Великобритания
Теперь я хочу поместить этот список в список списков, где он должен быть разделен на основе стран. Мой новый список списков должен выглядеть следующим образом
Количество: 1 — страна: США
Количество: 2 — страна: СШАКоличество: 3 — страна: IND
Количество: 4 — страна: Великобритания
Количество: 5 — страна: Великобритания
Количество может иметь любое целое число, а страна может иметь любую строку.
Есть ли какой-нибудь простой способ сделать это?
Комментарии:
1. @TheGeneral это пример. Я дополнительно обновил вопрос, чтобы он был менее запутанным.
2. итак, вы хотите иметь несколько списков?
3.Я думаю, вы немного смущены тем, что такое a на самом
List
деле, вашObject
abc
не список, у него есть только 2 свойства,count
и вcountry
нем нет элементов или коллекции, что делает его не aList
, если вам нужен список:Country
и aCount
, у вас может быть aList<string>
, в котором всеCountry
значения добавлены кзатем используйтеGroupBy
функцию, которая затем позволит вам использовать вcountry
качестве ключа, а затем получить общееCount
значение для этого ключа / страны4. я хочу список списков, так что да, несколько списков
5. @ConnorTJ я упомянул в первой строке, что это список типа abc
Ответ №1:
Вы можете использовать GroupBy и впоследствии выделить каждую группу в отдельный список:
List<abc> mylist = new List<abc>()
{
new abc{count = 1, country = "US"},
new abc{count = 2, country = "US"},
new abc{count = 3, country = "IND"},
new abc{count = 4, country = "UK"},
new abc{count = 5, country = "UK"},
};
List<List<abc>> result = mylist.GroupBy(x => x.country).Select(y => y.ToList()).ToList();
таким образом, вы получите список, содержащий 3 других списка
Ответ №2:
Реализовать это следующим образом:
List<abc> list = new List<abc>()
{
new abc() {country = "US", count = 1},
new abc() {country = "US", count = 2},
new abc() {country = "IND", count = 3},
new abc() {country = "UK", count = 4},
new abc() {country = "UK", count = 5}
};
Dictionary<string,List<abc>> dictionary = new Dictionary<string, List<abc>>();
foreach (var item in list)
{
if(!dictionary.TryGetValue(item.country,out var l))
{
l = new List<abc>();
dictionary.Add(item.country,l);
}
l.Add(item);
}
List<List<abc>> result = dictionary.Values.ToList();
Комментарии:
1. словарь.Значения. ToList(); является ли это допустимой функцией, и вы ожидаете, что она будет реализована?
2. Это действительно так.
Ответ №3:
вы можете сделать так.
List<abc> ls = new List<abc>();
ls.Add(new abc() { count = 1, country = "US" });
ls.Add(new abc() { count = 2, country = "US" });
ls.Add(new abc() { count = 3, country = "IND" });
ls.Add(new abc() { count = 4, country = "UK" });
ls.Add(new abc() { count = 5, country = "UK" });
List<List<abc>> listOfList = new List<List<abc>>();
foreach (var group in ls.GroupBy(x => x.country))
{
List<abc> list = new List<abc>();
foreach (var item in group)
{
list.Add(new abc() { count = item.count, country = item.country });
}
listOfList.Add(list);
}
LINQ
List<List<abc>> listOfList = new List<List<abc>>();
foreach (var (group, list) in from item in ls.GroupBy(x => x.country)
let temp = new List<abc>()
select (item, temp))
{
foreach (var item2 in group)
{
list.Add(new abc() { count = item2.count, country = item2.country });
}
listOfList.Add(list);
}
Ответ №4:
Как и многие уже ответившие, вы можете сгруппировать свой список по countryString
. Однако я лично предпочел бы добавить его в словарь, чтобы доступ был намного проще для понимания.
List<abc> myList = new List<abc>()
{
new abc{count = 1, country = "US"},
new abc{count = 2, country = "US"},
new abc{count = 3, country = "IND"},
new abc{count = 4, country = "UK"},
new abc{count = 5, country = "UK"},
};
Вы могли бы, как уже упоминалось, просто сгруппировать их:
var groupedLists = myList.GroupBy(x => x.country).Select(y => y.ToList()).ToList();
или вы можете создать из него словарь:
var myDictionary = myList.Select(item => item.country).Distinct().ToDictionary(country => country, country => myList.Where(item => item.country == country).ToList());
Теперь, имея словарь, вы можете получить доступ к определенному списку по ключу (страна). Например:
myDictionary["US"]; //would give you all items with the country "US"
Вам решать, что вы хотели бы использовать. Просто имейте в виду, что если вы используете словарь, вам необходимо обработать возможные keyNotFoundException
Ответ №5:
Самый простой способ сделать это с помощью Linq.
Вы можете использовать .GroupBy()
для создания группировок на основе значения свойства — в данном случае Country
.
В этом примере .Select()
оператор использует именованный кортеж, чтобы сделать данные немного более удобочитаемыми.
using System.Collections.Generic;
using System.Linq;
var data = new List<Abc>()
{
new()
{
Count = 1,
Country = "UK"
},
new()
{
Count = 2,
Country = "UK"
},
new()
{
Count = 3,
Country = "US"
}
};
var groupedData = data
.GroupBy(x => x.Country)
.Select(x => (Country: x.Key, Data: x.ToList()))
.ToList();
Способ использования и использования этого списка списков будет выглядеть так:
foreach (var (country, groupData) in groupedData)
{
var groupDataString = string.Join(" ", groupData.Select(x => x.Count));
Console.WriteLine($"{country}: {groupDataString}");
}
Пример вывода выглядит следующим образом:
UK: 1 2
US: 3