【问题标题】:Select subset from IDictionary based on IEnumerable<T> and return IEnumerable<T>根据 IEnumerable<T> 从 IDictionary 中选择子集并返回 IEnumerable<T>
【发布时间】:2018-08-16 23:50:20
【问题描述】:

我需要从IDictionary&lt;int,string&gt; 中选择一个数据子集来匹配来自IEnumerable&lt;T&gt; 的键,然后返回一个新的IEnumerable&lt;T&gt;。我被语法困住并得到错误:

方法 Extensions.GetValues<K, V>(IDictionary<K, V>, IEnumerable<K>) 的类型参数不能从 用法。尝试明确指定类型参数。

这是我的代码:

public class Subject
{
    public short SubjectID { get; set; }
    public byte CategoryID { get; set; }
    public string Title { get; set; }
}

public static class Extensions
{
    public static IEnumerable<V> GetValues<K, V>(this IDictionary<K, V> dict, IEnumerable<K> keys)
    {
        return keys.Select((x) => dict[x]);
    }
}

private IEnumerable<Subject> Translate()
{
   IEnumerable<Subject> selectedSubjects = new Subject[] { new Subject { SubjectID = 1, CategoryID = 2, Title = null } };

   // this is given externally as an IDictionary
   var dict = new Dictionary<int, string> 
   {
          { 1, "Hello" },
          { 2, "Goodbye" }
   };

   // this line produces the error: 
   IEnumerable<Subject> data = dict.GetValues(selectedSubjects);

   // would like to return IEnumerable<Subject> containing SubjectID = 1, CategoryID and Title = "Hello"
   return data;
}

我想我需要告诉它以某种方式使用SubjectID 作为short 过滤dict

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    好的,所以这将返回与字典匹配的主题列表(其中dict.key == Subject.SubjectID),更新Subject.Title = dict.value

    return dict.Keys.Join(
        selectedSubjects, 
        k => k, 
        s => (Int32)s.SubjectID, 
        (k, s) => new Subject
        {
            SubjectID = s.SubjectID, 
            CategoryID = s.CategoryID, 
            Title = dict[k] 
        });
    

    【讨论】:

    • 感谢您的回复。至少这解决了类型的问题,但它没有提供正确的数据。我实际上需要字典中的 int 和 string 值。在 SQL 伪中,它类似于 SELECT [ColumnINT], [ColumnSTRING] FROM Dictionary WHERE DictionaryID IN (selectedSubjects) - 然后将这些值返回给 IEnumerable&lt;Subject&gt;
    • 您的最新编辑不返回 IEnumerable,而是返回 IEnumerable
    • 对不起,你是对的,它从匹配 SubjectID 的字典中返回值。您希望返回匹配的主题,还是使用匹配字典键中的值更新主题,然后返回那些修改后的主题?
    • 我已经更新了这个问题。但是,是的,基本上它可以只为主题复制标题 - 也许我们可以完全摆脱过滤。
    • 好的,我已经更新了我的答案,这将返回一个标题为“你好”的主题。如果这是正确的,请标记我的答案。谢谢。很抱歉最初的混乱。
    【解决方案2】:

    尝试一个简单的yield IEnumerable。 EG

    public static IEnumerable<V> GetValues<K, V>(this IDictionary<K, V> dict, IEnumerable<K> keys)
    {
        foreach (var key in keys)
        {
            if (dict.TryGetValue(key, out V value))
            {
                yield return value;
            }
        }            
    }
    

    然后是这样的:

    var selectedSubjectIds = selectedSubjects.Select(s => s.SubjectID);
    IEnumerable<Subject> data = dict.GetValues(selectedSubjectIds);
    

    【讨论】:

    • 同样的错误,但感谢您的努力。我接受了 Carlo Bos 的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多