Любой способ упростить следующие два коротких фрагментов относительно словарь?


Пример 1

if (myList.ContainsKey(myKey))
{
    myList[myKey]++;
}
else
{
    myList.Add(myKey,1);
}

Пример 2

Where(x => 
(myList.ContainsKey(x.Key) ? x.Value - myList[x.Key] : x.Value) > 

класс MyList - это словарь.

Есть ли способ или существующий способ упрощения или нормализации кода?

Обновление

Теперь я выучил Python и наткнулся на defaultdict:



3270
8
задан 23 августа 2011 в 10:08 Источник Поделиться
Комментарии
7 ответов

Например, вы можете написать свой собственный метод extenession для этой операции и использовать ее везде. Что-то вроде этого

public static void SetOrIncrement<K>(this Dictionary<K, int> dictionary, K key)
{
int value;
if (dictionary.TryGetValue(key, out value))
{
dictionary[key] = value + 1;
}
else
{
dictionary[key] = 1;
}
}

И затем просто использовать его следующим образом:

 myList.SetOrIncrement(myKey);

7
ответ дан 24 августа 2011 в 06:08 Источник Поделиться

Также альтернативная:

if (!myList.ContainsKey(myKey))
{
myList.Add(myKey, 0);
}
myList[myKey]++;

11
ответ дан 24 августа 2011 в 07:08 Источник Поделиться

Давайте посмотрим, для

Where(x =>
(myList.ContainsKey(x.Key) ? x.Value - myList[x.Key] : x.Value) >

Я мог думать...

public static int GetSubtractedValueForMatchingKey<T>(this KeyValuePair<T,int> target, Dictionary<T,int> dictionaryToFindMatchingKey)
{
return dictionaryToFindMatchingKey.ContainsKey(target.Key) ?
(target.Value - dictionaryToFindMatchingKey[target.Key]) :
target.Value;
}

потом..

Where(x => x.GetSubtractedValueForMatchingKey(myList) >

1
ответ дан 24 августа 2011 в 12:08 Источник Поделиться

Пример 1:

var value = 0;

// value is treated as a reference type with the out modifier
if (myList.TryGetValue(myKey, out value))
{
myList[myKey] = value++; // I like this over myList[myKey]++

// either return here
}
// or wrap this in the else clause
myList.Add(myKey, value);

Пример 2: Когда метод возвращает bool

var value = -1;
var result = myList.Where(x => !myList.TryGetValue(myKey, out value))
.Select(x => value > -1 ? x.Value - value : x.Value);

Я не знаю, какие ваши ценности, но я считаю, что это достаточно близко, чтобы получить вас на верном пути. Он будет компилироваться, но я не дальнейшие испытания.

1
ответ дан 25 августа 2011 в 11:08 Источник Поделиться

Просто идея ...

public static void UpdateOrAdd<TKey, TValue>(
this Dictionary<TKey, TValue> source,
TKey key, Func<TValue, TValue> updateValue, Func<TValue> initializeValue )
{
TValue value;
if ( source.TryGetValue( key, out value ) )
{
source[ key ] = updateValue( value );

}
else
{
source.Add( key, initializeValue() );
}
}

Может быть использован как один-лайнер.

myList.UpdateOrAdd( myKey, v => v + 1, () => 1 );

Лямбда используется для инициализации так, что первоначальный объект для словарей со ссылочными типами создается только один раз.


Аналогичным образом вы можете сделать следующее, например 2.

public static TValue GetOrDefault<TKey, TValue>(
this Dictionary<TKey, TValue> source,
TKey key, TValue defaultValue )
{
return source.ContainsKey( key ) ? source[ key ] : defaultValue;
}

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

x.Value - myList.GetOrDefault( x.Key, 0 ) > ...

0
ответ дан 24 августа 2011 в 08:08 Источник Поделиться


класс MyList-это словарь

Я не пишу на C# и не знаю, какой словарь сконструировать, но я думаю, что вы смотрите на это карте. Каждое слово является ключевым элементом, так как он должен быть уникальным и значение, раз это слово встретил.

Так что в Яве , что бы быть такой:

import java.util.HashMap;
import java.util.Map;

/**
*
* @author c00kiemon5ter
*/
public class MapCountDict {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

/*
* A testing dictioary
*/
String[] dictionary = new String[]{ "foo", "foo", "foo", "bar", "bar", "yow" };

/*
* The collection to hold the times each word is found
*
* Each word is unique in the collection. The word is the key.
* The value is the times the word is met when going through
* the "dictionary".
*/
Map<String, Integer> occurances = new HashMap<String, Integer>();

/*
* Run through the dictionary, adding up the times each word is met.
*/
for (String word : dictionary) {
Integer value = occurances.get(word);
occurances.put(word, (value == null) ? 1 : value+1);
}

/*
* Print the results
*/
for (String word : occurances.keySet()) {
System.out.printf("%s\t%d\n", word, occurances.get(word));
}
}
}

Результаты:


yow   1
foo 3
bar 2

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

Надеюсь, что помогает немного.

0
ответ дан 31 августа 2011 в 01:08 Источник Поделиться

С точки зрения читабельности, мой голос идет за тернарным оператором:

myList[myKey]=(myList.ContainsKey(myKey))?myList[myKey]+=1:1;

Делает, что надо. Просто читать, и просто придумали для этой цели. Интересно, почему никто не придумал.

0
ответ дан 27 октября 2013 в 11:10 Источник Поделиться