Как я могу упростить боль инициализации словарей Списков в C#?

Все хорошо. Вам просто нужно изменить первую букву названия коллекции на верхний регистр.

Вместо

db.users.find();

Использовать

db.Users.find();

Надеюсь, это поможет ...

5
задан pupeno 15 May 2009 в 11:09
поделиться

6 ответов

Вы можете написать метод расширения - GetValueOrCreateDefault () или что-то в этом роде:

foreach (DataRow dr in ds.Tables[0].Rows)
{
    Foo.GetValueOrCreateDefault( dr["Key"] ).Add( dr["Value"].ToString() )
}

Может быть, вы даже можете написать метод расширения для всей инициализации?

7
ответ дан 18 December 2019 в 13:19
поделиться

Словарь списка ... в .NET 3.5, который будет ILookup . Реализация по умолчанию ( Lookup ) неизменна, но я написал EditableLookup для MiscUtil . Это будет намного проще в использовании - то есть

var data = new EditableLookup<string, int>();
data.Add("abc",123);
data.Add("def",456);
data.Add("abc",789);

foreach(int i in data["abc"]) {
    Console.WriteLine(i); // 123 & 789
}

Кроме этого, метод расширения:

public static void Add<TKey, TList, TValue>(
    this IDictionary<TKey, TList> lookup,
    TKey key, TValue value)
    where TList : class, ICollection<TValue>, new()
{
    TList list;
    if (!lookup.TryGetValue(key, out list))
    {
        lookup.Add(key, list = new TList());
    }
    list.Add(value);
}

static void Main() {
    var data = new Dictionary<string, List<string>>();
    data.Add("abc", "def");
}
4
ответ дан 18 December 2019 в 13:19
поделиться

Думаю, следует сделать следующее:

class DictionaryOfList : Dictionary<string, List<string>> {} 
  • Править Я должен прочитать более внимательно. Это не отвечает на вопрос. Tanascius has supplied a neat way to solve it.
2
ответ дан 18 December 2019 в 13:19
поделиться

Не забудьте директиву using .

Это не отвечает напрямую, но может быть в любом случае полезно. Использование псевдонима для общего типа коллекции может облегчить восприятие кода.

using StoreBox = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<string>>; 
using ListOfStrings = System.Collections.Generic.List<string>; 
class Program
{
    static void Main(string[] args)
    {
      var b = new StoreBox ();
      b.Add("Red", new ListOfStrings {"Rosso", "red" });
      b.Add("Green", new ListOfStrings {"Verde", "green" });
    }
}

Благодарим SO за эту подсказку.

0
ответ дан 18 December 2019 в 13:19
поделиться

Добавьте ссылку на System.Data.DataSetExtensions, и вы сможете использовать расширения Linq:

var dictOfLst = ds.Tables[0].Rows.
    //group by the key field
    GroupBy( dr => dr.Field<string>("key") ).
    ToDictionary(
        grp => grp.Key,
        //convert the collection of rows into values
        grp => grp.Select( dr => dr.Field<string>("value") ).ToList() );

Я не уверен, что возился бы с другим классом, но утилита или метод расширения могут сделайте это проще:

public static Dictionary<TKey, List<TValue>> ToGroupedDictionary<TKey, List<TValue>>(
    this DataTable input, 
    Func<TKey, DataRow> keyConverter, 
    Func<TValue, DataRow> valueConverter )
{
    return input.Rows.
        //group by the key field
        GroupBy( keyConverter ).
        ToDictionary(
            grp => grp.Key,
            //convert the collection of rows into values
            grp => grp.Select( valueConverter ).ToList() );
}

//now you have a simpler syntax
var dictOfLst = ds.Tables[0].ToGroupedDictionary(
    dr => dr.Field<string>("key"),
    dr => dr.Field<string>("value") );
1
ответ дан 18 December 2019 в 13:19
поделиться

Почему бы просто не упростить:

foreach (DataRow dr in ds.Tables[0].Rows)
{
   string key = dr["Key"].ToString();
   if (!Foo.ContainsKey(key)) Foo.Add(key, new List<string>());
   Foo[key].Add(dr["Value"].ToString());
}
0
ответ дан 18 December 2019 в 13:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: