2015-01-17 9 views
0

я в настоящее время печати значения определенного ключа, например, так:Перебора всего словаря, чтобы получить конкретное значение и ключ

 var myValue = dic1.FirstOrDefault(x => x.Key == "John").Value; 
     Console.WriteLine("John in dictionary: " + myValue); 

Значение Numer сколько раз Джон в этом словаре. Теперь я хотел бы сделать это для всего словаря. Есть идеи? Я думал о том, чтобы это что-то вроде этого:

  var dic1Dic2 = dic1.Zip(dic2, (d, z) => new { Dic1= d, Dic2 = z }); 
      foreach (var dz in dic1Dic2) 
      { 
       Console.WriteLine(dz.Dic1); 
       Console.WriteLine(dz.Dic2); 
      } 

Но в этом случае проблема, если один из списков меньше я не получаю значения. Черт, если у вас есть 100 слов и нет, если не будет printf.

Я хочу рассчитать, скажем, в dic1. Я получил ключ = четыре и значение = 4, а в dic2 я получил Four и value = 2 (например, он мог бы также 4, не имеет значения), и Я хочу их размножать или делить, или что угодно. В самом простом примере первого кода, когда я использую только конкретное значение ключа я делаю это так:

 var divideJohn = (myValue1/myValue); 

и myValue1 был из:

var myValue1 = dic2.FirstOrDefault(x => x.Key == "John").Value; 

Так любые идеи, как получить эти ценности из всего в словаре?

@edit Да, чтобы уточнить, у меня было много словарей, и я хочу, чтобы значения из каждого из них составляли некоторую математику. Для одного словаря делает петлю Еогеаспа может быть достаточно, как так:

 foreach (string item in dic1.Keys) 
     { 
      var dif = dic1.FirstOrDefault(x => x.Key == item).Value;         
     } 

Но все дело в том, чтобы получить их из Diferent словарей и иметь возможность использовать их в математике.

+2

'int value = dic1 [" Four "] * dic2 [" Four "]' - искать, как работает словарь, это O (1), не нужно итерации – BrokenGlass

+0

Но я хочу, чтобы итератор целый словарь, а не конкретный например, «четыре», но все же могут знать каждый результат конкретного примера, а также «четыре четыре». –

+0

«Если один из списков меньше, я не получаю значения». - Что бы вы хотели сделать в этом случае? Вы не указали - в противном случае использование 'Zip' отлично. – BrokenGlass

ответ

0

К сожалению, на ваш вопрос не совсем ясно, что вы пытаетесь сделать. Есть много деталей, оставшихся без внимания в вашем заявлении о проблеме, в котором однозначно будет указано, каково фактическое поведение.

Таким образом, похоже, что вы пытаетесь объединить свои словари. Очень простой вариант, это может быть:

Dictionary<string, int> MergeSum(
    Dictionary<string, int> dict1, Dictionary<string, int> dict2) 
{ 
    Dictionary<string, int> merged = new Dictionary<string, int>(dict1.Count); 

    foreach (var kvp in dict1) 
    { 
     merged.Add(kvp.Key, kvp.Value + dict2[kvp.Key]); 
    } 
} 

Примечание в приведенном выше есть неявное предположение, что оба словаря содержат одни и те же ключи. Альтернатива, которая не делает это предположение может выглядеть следующим образом:

Dictionary<string, int> MergeSum(
    Dictionary<string, int> dict1, Dictionary<string, int> dict2) 
{ 
    Dictionary<string, int> merged = new Dictionary<string, int>(dict1.Count); 

    foreach (var kvp in dict1) 
    { 
     int value; 

     dict2.TryGetValue(kvp.Key, out value); 
     merged.Add(kvp.Key, kvp.Value + value); 
    } 

    foreach (var kvp in dict2) 
    { 
     int value; 

     if (!dict1.TryGetValue(kvp.Key, out value)) 
     { 
      merged.Add(kvp.Key, kvp.Value); 
     } 
    } 
} 

Здесь value будет установлен в 0, если ее нет в словаре, когда TryGetValue() называется.

В вашем вопросе вы, кажется, указываете, что у вас может быть более двух словарей для слияния. В этом случае, вы можете взять в качестве входных данных массива словарей (или другой коллекции & hellip; массив просто удобен для целей иллюстрации):

Dictionary<string, int> MergeSum(Dictionary<string, int>[] dictionaries) 
{ 
    Dictionary<string, int> merged = new Dictionary<string, int>(); 

    foreach (Dictionary<string, int> dict in dictionaries) 
    { 
     foreach (var kvp in dict) 
     { 
      int value; 

      merged.TryGetValue(kvp.Key, out value); 
      merged[kvp.Key] = kvp.Value + value; 
     } 
    } 
} 

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

Dictionary<string, int> Merge(
    Dictionary<string, int>[] dictionaries, Func<int, int, int> mergeFunction) 
{ 
    Dictionary<string, int> merged = new Dictionary<string, int>(); 

    foreach (Dictionary<string, int> dict in dictionaries) 
    { 
     foreach (var kvp in dict) 
     { 
      int value; 

      merged.TryGetValue(kvp.Key, out value); 
      merged[kvp.Key] = mergeFunction(value, kvp.Value); 
     } 
    } 
} 

Вы могли бы назвать выше, как это:

result = Merge(dictionaries, (i1, i2) => i1 + i2); 

Некоторые операции являются более проблематичными, чем другие. Например, если вы используете умножение, то, поскольку код всегда агрегирует из пустого исходного словаря, результат операции агрегации всегда будет 0. Вы можете решить эту проблему с помощью специального кожухотрубного первого словаря:

Dictionary<string, int> Merge(
    Dictionary<string, int>[] dictionaries, Func<int, int, int> mergeFunction) 
{ 
    Dictionary<string, int> merged = new Dictionary<string, int>(dictionaries.First()); 

    foreach (Dictionary<string, int> dict in dictionaries.Skip(1)) 
    { 
     foreach (var kvp in dict) 
     { 
      int value; 

      merged.TryGetValue(kvp.Key, out value); 
      merged[kvp.Key] = mergeFunction(value, kvp.Value); 
     } 
    } 
} 

Это будет инициализировать словарь merged с первым словарем в коллекции, а затем пропустит этот словарь при выполнении фактического цикла агрегации. Но обратите внимание, что даже там у вас есть потенциальные проблемы при работе с ключами, отсутствующими в каждом словаре (например, при умножении, вы получите 0 в конечном результате, если в каком-либо словаре отсутствует этот ключ). Конечно, возможно, это то, чего вы действительно хотите.

Обратите также внимание на то, что, прежде всего, предполагается, что ваши значения: int. Но на самом деле ничего не существует в большинстве случаев, которые предполагают это. Пока у вас есть правильный способ комбинирования пары значений, вы можете легко изменить приведенный выше код, чтобы делать все, что хотите. Это включает в себя полностью родовую версию последнего примера:

Dictionary<TKey, TValue> Merge<TKey, TValue>(
    Dictionary<TKey, TValue>[] dictionaries, Func<TValue, TValue, TValue> mergeFunction) 
{ 
    Dictionary<TKey, TValue> merged = new Dictionary<TKey, TValue>(dictionaries.First()); 

    foreach (Dictionary<TKey, TValue> dict in dictionaries.Skip(1)) 
    { 
     foreach (var kvp in dict) 
     { 
      TValue value; 

      merged.TryGetValue(kvp.Key, out value); 
      merged[kvp.Key] = mergeFunction(kvp.Value, value); 
     } 
    } 
} 

(Отказ от ответственности:. Ни один из кода выше не был составлен заранее прошу прощения за опечатки, и предполагают, что выяснение того, что я на самом деле имел в виду не будет быть слишком сложным :)).

Наконец, обратите внимание, что есть Enumerable.ToDictionary() method. Я написал общую логику выше, но вы можете обнаружить, что вы можете использовать различные операции LINQ, включая метод ToDictionary(), чтобы упростить код и сделать его более выразительным из вашего фактического намерения (то есть, чтобы код показывал больше , что вы хотите сделать, а не как делаем).

Смежные вопросы