通过匹配枚举名称值对List<String>进行排序

3

我不太确定该如何做。我需要展示一个文件列表,这个列表的顺序与我们的文件服务器上所呈现的顺序不同。

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

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

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

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

    public enum ProcessWorkFlowOrder 
    {    
       File1,
       File3,
       File2           
    }

在列表中,"filenames"字符串值将与枚举名称完全匹配。

如何以最佳方式匹配并按其匹配的枚举值对“FileNames”列表进行排序?

3个回答

5
如果文件名完全匹配,我不会使用枚举,而是另外使用一个保持顺序的列表。
List<string> namesInOrder = ...
List<string> files = ...

var orderedFiles = from name in namesInOrder
                   join file in files 
                   on name equals file
                   select file;
< p > Join 保留第一个序列的顺序,因此您可以使用它来对第二个序列进行排序。


1
我同意Anthony的观点。在不混淆代码的情况下,Enum.ToString()看起来不错。但一旦你混淆了代码,任何使用Enum.ToString()的代码都将无法正常运行。 - Brian Dishaw
Brian: (1) 并非每个人都需要混淆代码,(2) 当你混淆代码时,可以选择不混淆特定枚举类型的字段。 - configurator
当然,这一切都是真的。我想指出使用Enum.ToString()和混淆时需要注意的问题。特别是因为他没有指定代码是否被混淆。 - Brian Dishaw
不加密,但感谢评论,Anthony我喜欢你的答案,刚试了一下,完美地解决了问题。如果有人知道如何通过枚举名称来实现它,那就很酷了。 - proggrock
@ProgRockCode 我认为我的答案符合原始要求,或者我错了吗? - Jodrell

3

如果您已经有了枚举类型,而又不能像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的定义”的错误。 - proggrock
这里使用了 Linq;请在文件顶部添加 using System.Linq; - configurator
如果使用 System.Linq 没有帮助,请尝试这样转换:Enum.GetValues(typeof(ProcessWorkFlowOrder)).Cast<ProcessWorkFlowOrder>().Select(... - danyolgiax
@danyolgiax:这是不必要的 - 当lambda接受一个Object时,你可以看到它完美地工作 - 它在获取值时进行强制转换。 - configurator
1
我现在已经编辑了我的代码,确保使用 OfType 正确地对枚举进行了类型化。 - configurator
显示剩余2条评论

1

怎么样?

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;
    });

你会使用什么规则来构建枚举或者有序列表?还是说顺序完全是任意的?

如果任何文件没有有效的枚举值,这将导致崩溃和失败;由于枚举没有TryParse,您无法轻松地过滤掉它们,除非进行额外的步骤:Select(f => Enum.IsDefined(typeof(ProcessWorkFlowOrder), f)) - configurator
@configurator,完全同意,但是使用枚举来推导顺序的本质问题就在于此。不过可以使用TryParse。 - Jodrell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接