C# 从字典C检索值的一种改进方法

C# 从字典C检索值的一种改进方法,c#,dictionary,C#,Dictionary,我目前有一个带有int键的字典,该值是一个名为MachinePart的类的实例 关键在于机器零件是什么类型的机器零件。例如,如果键在0-99之间,则机器零件属于称为自由移动的类别。如果键在100-199之间,则机器零件属于其他类别,依此类推 因此,有一个从字典中检索特定类别的方法是很有用的。澄清返回钥匙在一定范围内的机器零件列表 下面是我目前必须检索自由运动部件的代码。它工作得很好,但是我想知道是否有一种更完善的方法来编写它,而不是必须有一个循环,循环重复99次 public static L

我目前有一个带有int键的字典,该值是一个名为MachinePart的类的实例

关键在于机器零件是什么类型的机器零件。例如,如果键在0-99之间,则机器零件属于称为自由移动的类别。如果键在100-199之间,则机器零件属于其他类别,依此类推

因此,有一个从字典中检索特定类别的方法是很有用的。澄清返回钥匙在一定范围内的机器零件列表

下面是我目前必须检索自由运动部件的代码。它工作得很好,但是我想知道是否有一种更完善的方法来编写它,而不是必须有一个循环,循环重复99次

 public static List<MachinePart> getFreeMovementParts(Dictionary<int, MachinePart> iMachineParts)
    {
        List<MachinePart> temp = new List<MachinePart>();
        for (int i = 0; i < 99; i++)
        {
            MachinePart t;
            if (iMachineParts.TryGetValue(i, out t))
            {
                temp.Add(t);
            }
        }
        return temp;

    }

您可以使用Linq选择以下值:

var freeMovementParts = iMachineParts.Where(it => it.Key >= 0 && it.Key <= 99)
                                     .Select(it => it.Value)
                                     .ToList();

但正如评论中所建议的,最好为实现考虑一种替代的数据结构。此外,值得注意的是,如果字典包含大量项,则对键进行迭代将导致性能低下,并且您将失去使用字典的性能优势。

如果您想对代码进行Linq验证,可以执行以下操作:

    public static List<MachinePart> getFreeMovementParts(Dictionary<int, MachinePart> iMachineParts)
    {
        return Enumerable.Range(0, 99)
            .Select(i => { iMachineParts.TryGetValue(i, out var mp); return mp; })
            .Where(mp => mp != null)
            .ToList();
    }
它并不能解决评论中提到的问题,不同的数据结构可能更合适,上面的大部分只是为了好玩


此方法的性能与枚举所有密钥方法的性能比较-它类似于DB索引,在小数据集上,执行完全扫描枚举所有密钥通常更便宜。但是,当您只需要大字典中的一小部分项时,基于已知的键范围查找项会更便宜。

int键的确切用途是什么?如果没有进一步的信息,听起来像是使用一个带有枚举的目录作为键,列表作为值,可能是一个更好的解决方案。标准词典假设键是独立的,因此,如果不像您所做的那样单独请求每个键,就无法说获取键在此范围内的所有值。但您可以做的是创建一个更复杂的数据结构,并针对您的目的进行优化。例如,如果你的整数都是nnxx格式的,那么你可以有一个字典,其中nn是一个键,零件列表是它的值,这样你就可以一次得到类别nn的所有零件。这是否有效将取决于您的数据,但如果不是,则类似的内容应该是可能的…字典,其中第一个键是id/100,第二个键是id。要添加到@Chris,将数据存储在多个表示中通常不是一个坏的解决方案。维护两个字典,一个是id:MachinePart,另一个是categoryID:List,这通常不是一个可怕的记忆负担。当然,这取决于您的具体需求。使用linq,您可能会得到一个外观更好的解决方案,但速度方面不行。正如另一位所说,您可能应该考虑一个适合您需要的自定义对象。如果你只有一个等级,@jeroemostert解决方案是非常好的。如果您需要更多级别,您可以查看允许递归树结构的复合模式。虽然此解决方案在阅读方面更加优雅,但性能不如您的解决方案,尤其是如果您的字典包含大量项,它将循环所有字典项。
    var r = from part in iMachineParts
                where part.Key >= 0 && part.Key <= 99
                select part.Value;

        return r.ToList();