使用LINQ将货币字典分组

时间:2015-04-25 09:53:11

标签: c# linq dictionary

我有一本货币词典:

Dictionary<string, string>
        _currencies = CultureInfo.GetCultures(CultureTypes.SpecificCultures)
                        .Select(c => new RegionInfo(c.LCID))
                        .Where(ri => ri != null)
                        .GroupBy(ri => ri.ISOCurrencySymbol)
                        .ToDictionary(x => x.Key, x => x.First().CurrencyEnglishName);

我想把它们分成一组流行货币和其他货币。

到目前为止,我正在这样做,但我不喜欢它:

List<string> popularCurrencies = new List<string>
{
    "GBP", "EUR", "USD", "AUD", "CNY", "INR", "SGD"
};

List<Currency> popular = _currencies
    .Where(kvp => popularCurrencies.Contains(kvp.Key))
    .Select(kvp => new Currency
    {
        Id = kvp.Key,
        Name = kvp.Key + " - " + kvp.Value,
        Category = "Popular"
    })
    .ToList();

List<Currency> other = _currencies
    .Where(kvp => !popularCurrencies.Contains(kvp.Key))
    .Select(kvp => new Currency
    {
        Id = kvp.Key,
        Name = kvp.Key + " - " + kvp.Value,
        Category = "All"
    })
    .ToList();

List<Currency> all = popular.Concat(other).ToList();

public class Currency 
{
  public string Id { get; set; }
  public string Name { get; set; }
  public string Category { get; set; }
}

我以为我可以将2个linq查询和Concat分成1行。

更新:

我添加了对热门货币的订购。我想知道是否有一种简单的方法可以对其余的进行排序。

                Dictionary<string, int> popularCurrencies = new Dictionary<string, int>() {
                {"GBP", 1},{"EUR", 2},{"USD", 3},{"AUD", 4},{"CNY", 5},{"INR", 6},{"SGD", 7}
            };
                var all = _currencies.Select(kvp => new Currency
            {
                Id = kvp.Key,
                Name = kvp.Key + " - " + kvp.Value,
                Category = popularCurrencies.Any(c => c.Key == kvp.Key) ? "Popular" : "All"
            }).OrderByDescending(c => c.Category).OrderBy(c => popularCurrencies.ContainsKey(c.Id) ? popularCurrencies[c.Id] : int.MaxValue).ToList();

2 个答案:

答案 0 :(得分:2)

你可以试试这个:

var all = _currencies.Select(kvp => new Currency
{
    Id = kvp.Key,
    Name = kvp.Key + " - " + kvp.Value,
    Category = popularCurrencies.Any(c => c == kvp.Key) ? "Popular" : "All"    
}).ToList()

<强>加了: 如果您想首先使用热门货币,可以添加OrderByDescending

var all = _currencies.Select(kvp => new Currency
{
    Id = kvp.Key,
    Name = kvp.Key + " - " + kvp.Value,
    Category = popularCurrencies.Any(c => c == kvp.Key) ? "Popular" : "All"    
}).OrderByDescending(c => c.Category).ToList()

答案 1 :(得分:1)

您可以按照常用货币列表中的匹配项对货币进行分组,然后将这两个组展平(SelectMany)为Currency个对象:

_currencies.GroupBy(x => popularCurrencies.Contains(x.Key) ? "Popular" : "All")
           .SelectMany(g => g.Select(x => new Currency 
                                          { 
                                              Id = x.Key, 
                                              Name = x.Key + " - " + x.Value, 
                                              Category = g.Key 
                                          }))

如果您使用Select代替SelectMany,则查询将返回两个组。你问题的标题表明这就是你所追求的。

如果您想按特定订单订购一个组,您可以

_currencies.GroupBy(x => popularCurrencies.Contains(x.Key) ? "Popular" : "All")
           .SelectMany(g => g.OrderBy(x => g.Key == "All" 
                                                      ? x.OrderByProperty 
                                                      : "" // or e.g. 0
                             .Select(x => new Currency 
                                          { 
                                              Id = x.Key, 
                                              Name = x.Key + " - " + x.Value, 
                                              Category = g.Key 
                                          }))