从Dictionary中删除可空值并重新输入类型

时间:2015-07-24 01:14:49

标签: c# .net

想象一下,我有以下枚举:

<script>

$("button").click(function(){
    $("#flexMenu").toggle("slow", function() {

});
});

</script>

#flexMenu { /* display: inline-block;*/ position: fixed; float: left; background: #1f1f1f; margin: 3.9em 0 0 0; padding: .25em; width: 15%; height: 6em; border: 2px solid #fff; z-index: 100; }

public enum CompassDirection
{
    North,
    East,
    South,
    West
}

如何从字典中优雅地删除Dictionary<string, CompassDirection?>值,或复制到新词典,然后返回var dictionary = new Dictionary<string, CompassDirection?> { { "Foo", CompassDirection.North }, { "Bar", null }, { "Baz", CompassDirection.West } }; (请注意null的通用参数现在不可为空)

我能想到的一个解决方案是:

Dictionary<string, CompassDirection>

没有复制是否有更好的方法?

3 个答案:

答案 0 :(得分:0)

IMO,只要你说“优雅地删除null”,你就会有高度自以为是的答案。

如果你发现它们很优雅,你可以使用两种方法(1 Linq和1非 - Linq)。可空类型具有HasValue属性,以确定是否为null。如果类型HasValue属性为true,则可以引用Value属性,这样就不必强制转换为CompassDirection

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main(string[] args)
    {
        var dictionary = new Dictionary<string, CompassDirection?>
        {
            { "Foo", CompassDirection.North },
            { "Bar", null },
            { "Baz", CompassDirection.West }
        };

        Console.WriteLine("New Dictionary 1:");
        PrintDictionary(RemoveNullMethod1(dictionary));

        Console.WriteLine("New Dictionary 2:");     
        PrintDictionary(RemoveNullMethod2(dictionary));
    }

    public static Dictionary<string, CompassDirection> RemoveNullMethod1(Dictionary<string, CompassDirection?> input)
    {
        return input
            .Where(entry => entry.Value.HasValue)
            .ToDictionary(e => e.Key, e => e.Value.Value);
    }

    public static Dictionary<string, CompassDirection> RemoveNullMethod2(Dictionary<string, CompassDirection?> input)
    {
        Dictionary<string, CompassDirection> newDictionary = new Dictionary<string, CompassDirection>();
        foreach(KeyValuePair<string, CompassDirection?> entry in input)
        {
            if (entry.Value.HasValue)
            {
                newDictionary.Add(entry.Key, entry.Value.Value);
            }
        }
        return newDictionary;
    }

    public static void PrintDictionary(Dictionary<string, CompassDirection> input)
    {
        foreach(KeyValuePair<string, CompassDirection> entry in input)
        {
            Console.WriteLine("Key: {0} Value: {1}", entry.Key, entry.Value);
        }
        Console.WriteLine();
    }
}

public enum CompassDirection
{
    North, East, South, West
}

结果:

New Dictionary 1:
Key: Foo Value: North
Key: Baz Value: West

New Dictionary 2:
Key: Foo Value: North
Key: Baz Value: West

Fiddle Demo

答案 1 :(得分:0)

我编写了一个通用的扩展方法来解决我的问题:

public static class KeyValuePairHelpers
{
    public static IEnumerable<KeyValuePair<TKey, TValue>> 
        ToValueNonNullableKvps<TKey, TValue>(
            this IEnumerable<KeyValuePair<TKey, TValue?>> input)
            where TValue : struct
    {
        return from kvp in input
               where kvp.Value.HasValue
               select new KeyValuePair(kvp.Key, (TValue)kvp.Value);
    }

用法:

var dictionary = new Dictionary<string, CompassDirection?>
{
    { "Foo", CompassDirection.North },
    { "Bar", null },
    { "Baz", CompassDirection.West }
};
var nonNullableKvps = dictionary.ToValueNullableKvps(); 
// Type of nonNullableKvps is now IEnumerable<KeyValuePair<string, CompassDirection>>

答案 2 :(得分:0)

其他答案重建一个全新的字典。如果我们不做那么疯狂的事情怎么样?

var badkeys = dictionary.Where(kvp => !kvp.Value.HasValue).Select(kvp => kvp.Key).ToArray();
foreach(var key in badkeys)
    dictionary.Remove(key);