Program Tip

C # 일반 사전에서 값 필터링

programtip 2020. 11. 26. 19:44
반응형

C # 일반 사전에서 값 필터링


Dictionary<Guid, MyObject>속성에 따라 필터링해야하는 C # 사전 이 있습니다 MyObject.

예를 들어 사전에서 모든 레코드를 제거하고 싶습니다 MyObject.BooleanProperty = false. 이것을 달성하는 가장 좋은 방법은 무엇입니까?


Dictionary를 구현하므로 IEnumerable<KeyValuePair<Key, Value>>다음을 사용할 수 있습니다 Where.

var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);

필요한 경우 새 사전을 다시 만들려면 ToDictionary방법을 사용하십시오 .


원하는 항목으로 새 사전을 만들고 이전 사전을 버리는 데 관심이 없다면 다음을 시도하십시오.

dic = dic.Where(i => i.Value.BooleanProperty)
         .ToDictionary(i => i.Key, i => i.Value);

새 사전을 만들 수없고 어떤 이유로 든 이전 사전을 변경해야하는 경우 (예 : 외부에서 참조되고 모든 참조를 업데이트 할 수없는 경우) :

foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList())
    dic.Remove(item.Key);

참고 ToList이 기본 모음을 수정하고 있기 때문에 여기에 필요하다. 기본 컬렉션을 변경하면 값을 쿼리하기 위해 작업하는 열거자를 사용할 수 없으며 다음 루프 반복에서 예외가 발생합니다. ToList사전을 변경하기 전에 값을 캐시합니다.


Linq where 절을 사용하면됩니다 .

var filtered = from kvp in myDictionary
               where !kvp.Value.BooleanProperty
               select kvp

    public static Dictionary<TKey, TValue> Where<TKey, TValue>(this Dictionary<TKey, TValue> instance, Func<KeyValuePair<TKey, TValue>, bool> predicate)
    {
        return Enumerable.Where(instance, predicate)
                         .ToDictionary(item => item.Key, item => item.Value);
    }

내 프로젝트에 IDictionary를 필터링 할 수있는 다음 확장 방법을 추가했습니다.

public static IDictionary<keyType, valType> KeepWhen<keyType, valType>(
    this IDictionary<keyType, valType> dict,
    Predicate<valType> predicate
) {
    return dict.Aggregate(
        new Dictionary<keyType, valType>(),
        (result, keyValPair) =>
        {
            var key = keyValPair.Key;
            var val = keyValPair.Value;

            if (predicate(val))
                result.Add(key, val);

            return result;
        }
    );
}

용법:

IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29);

다음은 값의 부울 속성뿐만 아니라 일반적인 솔루션입니다.

방법

알림 : 확장 메서드는 정적 클래스에 배치해야합니다. using System.Linq;소스 파일의 맨 위에 있는 문장을 잊지 마십시오 .

    /// <summary>
    /// Creates a filtered copy of this dictionary, using the given predicate.
    /// </summary>
    public static Dictionary<K, V> Filter<K, V>(this Dictionary<K, V> dict,
            Predicate<KeyValuePair<K, V>> pred) {
        return dict.Where(it => pred(it)).ToDictionary(it => it.Key, it => it.Value);
    }

용법

예:

    var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0);

참고URL : https://stackoverflow.com/questions/2131648/filtering-out-values-from-a-c-sharp-generic-dictionary

반응형