Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在LINQ中对路径列表排序?_Linq_Sorting_Path_Hierarchy_Flatten - Fatal编程技术网

在LINQ中对路径列表排序?

在LINQ中对路径列表排序?,linq,sorting,path,hierarchy,flatten,Linq,Sorting,Path,Hierarchy,Flatten,假设我有以下文件夹: New Folder - New Folder - New Folder (2) - New Folder (3) - New Folder (4) New Folder (2) New Folder (3) New Folder (4) 还有一个问题 from s in Directory.GetDirectories(@"D:\Project\uploads", "*.*", SearchOption.AllDirectories) select s 结果是: D:

假设我有以下文件夹:

New Folder
- New Folder
- New Folder (2)
- New Folder (3)
- New Folder (4)
New Folder (2)
New Folder (3)
New Folder (4)
还有一个问题

from s in Directory.GetDirectories(@"D:\Project\uploads", "*.*", SearchOption.AllDirectories)
select s
结果是:

D:\Project\uploads\New Folder
D:\Project\uploads\New Folder (2)
D:\Project\uploads\New Folder (3)
D:\Project\uploads\New Folder (4)
D:\Project\uploads\New Folder\New Folder
D:\Project\uploads\New Folder\New Folder (2)
D:\Project\uploads\New Folder\New Folder (3)
D:\Project\uploads\New Folder\New Folder (4)
是否有方法将列表按正确顺序排序?我希望是:

D:\Project\uploads\New Folder
D:\Project\uploads\New Folder\New Folder
D:\Project\uploads\New Folder\New Folder (2)
D:\Project\uploads\New Folder\New Folder (3)
D:\Project\uploads\New Folder\New Folder (4)
D:\Project\uploads\New Folder (2)
D:\Project\uploads\New Folder (3)
D:\Project\uploads\New Folder (4)
任何帮助都将不胜感激

使用.NET4.0试试看

 Directory.EnumerateDirectories(@"D:\Project\uploads", "*.*", SearchOption.AllDirectories) 
它可能会做你期望的事情。如果没有,您可以显式执行:

 Directory.GetDirectories(@"D:\Project\uploads")
      .SelectMany(dir => dir.GetDirectories().OrderBy(sub => sub.Name))
最后,您可以执行以下操作:

 from s in Directory.GetDirectories(@"D:\Project\uploads", "*.*", SearchOption.AllDirectories)
 order by s.Parent.Name, s.Name
 select s

 from s in Directory.GetDirectories(@"D:\Project\uploads", "*.*", SearchOption.AllDirectories)
 let members = s.Name.Split(new [] {Path.SeparatorChar})
 order by members[2], s.Name
 select s

以获得更大的控制/灵活性。根据您的需要选择最简单的方法

关于默认顺序,您唯一需要更改的是确保
\
字符始终被视为字母表中的第一个字母。我没有一个确切的答案如何实现这一点,但是:

  • 如果找到一种方法将字符串中的
    \
    替换为小于所有其他字符的字符,并将替换后的字符串用作键,则可以使用
    order by
    子句

  • 您可以使用
    Array.Sort
    并实现重新实现字符串比较的字符串比较器,但对
    \
    字符的附加规则进行编码


    • 这并不像我想的那么琐碎。也许最明智的解决方案(除了递归地构建列表之外)是实现一个比较器来进行排序


      谢谢你的评论和回答,伙计们

      我想有了递归,生活会轻松得多

      void Main()
      {
          string rootFolder = @"D:\Project\uploads";
      
          string[] f = Directory.GetDirectories(rootFolder, "*.*", SearchOption.AllDirectories);
      
          Func<string, string[]> build = null;
      
          build = (p) => {
              return (from x in f where Path.GetDirectoryName(x) == p
                      from y in new string[]{ x }.Union(build(x)) select y).ToArray();
          };
      
          f = build(rootFolder).Dump();
      }
      
      void Main()
      {
      string rootFolder=@“D:\Project\uploads”;
      字符串[]f=Directory.GetDirectories(rootFolder,*.*,SearchOption.AllDirectories);
      Func build=null;
      构建=(p)=>{
      返回(从f中的x开始,其中Path.GetDirectoryName(x)=p
      从新字符串[]{x}.Union(build(x))中的y中选择y.ToArray();
      };
      f=构建(rootFolder.Dump();
      }
      
      嗯,我没想到那一个。
      GetDirectories()
      是否保证按排序顺序返回目录?否则你必须对它进行排序。我认为第二个版本需要是递归的。@Tomas:我也可以这样想,但它在任何地方都不明确,让OP决定你也可以为此目的对你的区域设置cultureinfo进行黑客攻击。我建议你“说出你的意思”(有意编程)@NVA:是的,我刚刚注意到这个。。。不是我在某些输入上预期的顺序。让我看看是否可以调整它。@Byul:我发现了如何实现这样一个比较器。所以,如果你想通过排序来实现这一点,你可以使用这个比较器。p、 美国,名称变更?:)哦,伙计,我不知道使用顺序比较器会有什么不同,尽管在这里制作一个新的比较器并不是真的必要。是的。你是对的。x=>x.Replace(Path.directoryseportorchar,'\0')是使用StringComparer.Ordinal comparer的一个很好的键选择器
      var query = Directory
          .EnumerateDirectories(@"D:\Project\uploads", "*", SearchOption.AllDirectories)
          .OrderBy(name => name.Replace(Path.DirectorySeparatorChar, '\0'), StringComparer.Ordinal);
      
      void Main()
      {
          string rootFolder = @"D:\Project\uploads";
      
          string[] f = Directory.GetDirectories(rootFolder, "*.*", SearchOption.AllDirectories);
      
          Func<string, string[]> build = null;
      
          build = (p) => {
              return (from x in f where Path.GetDirectoryName(x) == p
                      from y in new string[]{ x }.Union(build(x)) select y).ToArray();
          };
      
          f = build(rootFolder).Dump();
      }
      
      private class Comparer : IComparer<string>
      {
          public int Compare(string x, string y)
          {
              return StringComparer.Ordinal.Compare(x.Replace(Path.DirectorySeparatorChar, '\0'),
                                                      y.Replace(Path.DirectorySeparatorChar, '\0'));
          }
      }
      
      var source = Directory.GetDirectories(@"D:\Project\uploads", "*.*", SearchOption.AllDirectories)
      var target = source.OrderBy(x => x, new Comparer()).ToArray();