【问题标题】:Ordering a List<String> by matched Enum's name value通过匹配的 Enum 的名称值对 List<String> 进行排序
【发布时间】:2011-05-24 15:26:56
【问题描述】:

有点不确定如何做到这一点。我需要以与文件服务器上显示的顺序不同的顺序显示文件列表。

我在想一种方法是通过匹配的枚举名称值对字符串列表进行排序。

假设我有一个完整的字符串列表:

    List<string> filenames = new List<string>();

我有一个相关的枚举来按特定顺序显示文件:

    public enum ProcessWorkFlowOrder 
    {    
       File1,
       File3,
       File2           
    }

列表中的“文件名”字符串值将与枚举的名称完全匹配。

根据匹配的枚举值匹配和排序 FileNames 列表的最佳方法是什么?

【问题讨论】:

    标签: c# linq list enums matching


    【解决方案1】:

    如果文件名完全匹配,我不会使用枚举,而是使用另一个保留顺序的列表。

    List<string> namesInOrder = ...
    List<string> files = ...
    
    var orderedFiles = from name in namesInOrder
                       join file in files 
                       on name equals file
                       select file;
    

    Join 保留第一个序列的顺序,因此允许您使用它来订购第二个。

    【讨论】:

    • 我同意安东尼的观点。只要您不混淆代码,Enum.ToString() 看起来就不错。混淆后,任何使用 Enum.ToString() 的代码都将停止运行。
    • Brian:(1) 不是每个人都需要混淆,(2) 当您混淆时,您可以选择不混淆特定枚举的字段。
    • 当然,这一切都是真的。我想指出使用 Enum.ToString() 和混淆的问题。特别是因为他没有说明代码是否被混淆。
    • 没有混淆,但感谢 cmets,Anthony 我喜欢你的回答,刚刚试了一下,效果很好。如果有人确实有办法通过 Enum 名称做到这一点,那会很酷吗?
    • @ProgRockCode 我认为我的回答与原始简报相符还是我错了?
    【解决方案2】:

    如果您已经拥有枚举并且无法像 Anthony 建议的那样将其更改为字符串列表,则可以使用:

    var order = Enum.GetValues(typeof(ProcessWorkFlowOrder))
                    .OfType<ProcessWorkFlowOrder>()
                    .Select(x => new {
                                       name = x.ToString(),
                                       value = (int)x
                            });
    
    var orderedFiles = from o in order
                       join f in filenames
                       on o.name equals f
                       orderby o.value
                       select f;
    

    【讨论】:

    • 看起来很有希望,但我得到 'System.Array 不包含 Select 的定义'
    • 这使用了 Linq;在文件顶部添加using System.Linq;
    • 如果使用 System.Linq 添加并不能帮助尝试这种方式投射:Enum.GetValues(typeof(ProcessWorkFlowOrder)).Cast&lt;ProcessWorkFlowOrder&gt;().Select(...
    • @danyolgiax:这是不必要的——你可以看到 lambda 在接受 Object 时工作得非常好——它在获取值时进行转换。
    • 我现在已经将我的代码编辑为正确,OfType 确保枚举输入正确。
    【解决方案3】:

    怎么样?

    var orderedFilenames = filenames.OrderBy(
        f => (int)Enum.Parse(typeof(ProcessWorkFlowOrder), f));
    

    但是,我不确定维护这个枚举是最好的方法,最好写一个函数来定义顺序算法,如果枚举不包含文件名怎么办。

    使用 TryParse 编辑

    var orderedFilenames = filenames.OrderBy(f => {
           ProcessWorkFlowOrder parsed;
           int result = 0;
           if (Enum.TryParse<ProcessWorkFlowOrder>(f, out parsed))
               result = (int)parsed;
           return result;
        });
    

    你会使用什么规则来构造枚举或顺序保留列表,或者顺序是否纯粹是任意的?

    【讨论】:

    • 如果任何文件没有有效的枚举值,这将崩溃并烧毁;由于 enum 没有 TryParse ,因此如果没有额外的步骤,您将无法轻松过滤掉它们:Select(f =&gt; Enum.IsDefined(typeof(ProcessWorkFlowOrder), f))
    • @configurator,完全同意,但这本质上是使用枚举派生顺序的问题。但是可以使用 TryParse。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2022-01-10
    • 2021-03-26
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多