linq 根据文件名中数字的可变长度对文件进行排序C#

nqwrtyyt  于 2023-01-15  发布在  C#
关注(0)|答案(1)|浏览(149)

我正在写一个程序来监视搅拌机渲染项目。但是我有一个排序搅拌机(一个3d程序)输出的问题。它生成数字格式的文件。或者在一些文本然后以数字格式结束。
这里的问题是,它的数字如下:
someprojectname-0001.png
someprojectname-0010.png
someprojectname-10104.png

某个项目名称-10105.png
某个项目名称-9999.png

数字之前可能有一些文本,但问题是,到目前为止,我尝试的任何排序都看到9999高于10104(有些问题是额外的数字,数字的数量也不固定)。
它应该输出
someprojectname-0001.png
someprojectname-0010.png

**某个项目名称-9999.png

项目名称-10104.png**
基本上concat所有数字(忽略任何文本),然后按数字排序,所以我尝试:

d = new DirectoryInfo(renderpath);

//  FileInfo[] files = d.GetFiles( rendertpye).OrderBy(p => p.Name).ToArray();

FileInfo[] files = d.GetFiles(rendertpye).OrderByDescending(o => string.IsNullOrEmpty(o.Name)).ThenBy(o =>
            {
                int result;
                if (Int32.TryParse(o.Name, out result))
                { return result; }
                else
                { return Int32.MaxValue; }
            }).ToArray();

我还尝试了数字前阿尔法排序(https://www.codeproject.com/Tips/543502/Numeric-before-alpha-sort-in-LINQ),我尝试了(https://www.dotnetperls.com/alphanumeric-sorting)。
这个问题,虽然他们都不能处理非固定的数字长度的搅拌机文件编号。

update我在这里的目标不是给人们如何保存他们的BlendFiles设置规则,程序需要一个数组来检索所有保存的文件,并根据文件名中的数字进行排序,文件名可以是可变的数字大小。

我用Linq试过了,但我开始怀疑它是否能直接用Linq完成,也许可以,如果我们基于文件名创建一个int列表,然后对该列表排序,并使用该列表对名为list的原始文本排序。

goucqfw6

goucqfw61#

解决了这个问题,创建了一个struct(这不是理想的),在这个struct上我为每个fileinfo条目添加了一个int计数器,还有一些regex来擦除文件名中的文本,这个函数保留了原始的名称,fileInfo但是返回的是它们所包含的数字排序。
一个未来的扩展可能是也对最后修改的属性进行排序,这可能会更容易。一个轻微的改进可能是只在名称的末尾查找数字,因为project 2-frame33.blend会有问题。也许一些聪明的正则表达式可以做到这一点。

struct numericfile
    {
        public int filenr; public FileInfo file;
    }
public List<FileInfo> SortedbyNumber(List<FileInfo> files)
    {
        List<numericfile> filesnrs = new List<numericfile>();
        foreach (FileInfo file in files)
        {
            numericfile nf = new numericfile();
            nf.filenr = Convert.ToInt32(Regex.Replace(file.Name, "[^0-9]+", string.Empty));
            nf.file = file;
            filesnrs.Add(nf);
        }
        filesnrs.Sort((s1, s2) => s1.filenr.CompareTo(s2.filenr));
        files.Clear();
        foreach (numericfile fnr in filesnrs)
        {
            files.Add(fnr.file);
        }
        return files;
    }

相关问题