how to extract common file path from list of file paths in c#

后端 未结 9 1452
粉色の甜心
粉色の甜心 2021-01-17 15:42

What is the best way extract the common file path from the list of file path strings in c#?

Eg: I have a list 5 file paths in List variable, like below

c:\

相关标签:
9条回答
  • 2021-01-17 16:28

    Because everything is best solved with LINQ*:
    *not everything is best solved with LINQ.

    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    
    class Program
    {
        static void Main(string[] args)
        {
            List<string> Files = new List<string>()
            {
                @"c:\abc\pqr\tmp\sample\b.txt",
                @"c:\abc\pqr\tmp\new2\c1.txt",
                @"c:\abc\pqr\tmp\b2.txt",
                @"c:\abc\pqr\tmp\b3.txt",
                @"c:\a.txt"
            };
    
            var MatchingChars =
                from len in Enumerable.Range(0, Files.Min(s => s.Length)).Reverse()
                let possibleMatch = Files.First().Substring(0, len)
                where Files.All(f => f.StartsWith(possibleMatch))
                select possibleMatch;
    
            var LongestDir = Path.GetDirectoryName(MatchingChars.First());
        }
    }
    

    Explanation:

    The first line gets a list of lengths of possible matches to evaluate. We want the longest possibility first (so i reverse the enumeration which would be 0, 1, 2, 3; turning it into 3, 2, 1, 0).

    I then get the string to match, which is simply a substring of the first entry of the given length.

    I then filter the results, to ensure we only include possible matches that all files start with.

    Finally, i return the first result, which will be the longest substring and call path.getdirectoryname to ensure if something has a few identical letters in the filenames it isn't included.

    0 讨论(0)
  • 2021-01-17 16:28

    Keep a tally of each segment and keep going while all the paths start with the tally.

    void Main()
    {
        string[] paths = new[] { @"c:\abc\pqr\tmp\sample\b.txt",
                                @"c:\abc\pqr\tmp\new2\c1.txt",
                                @"c:\abc\pqr\tmp\b2.txt",
                                @"c:\abc\pqr\tmp\b3.txt",
                                @"c:\abc\pqr\tmp\tmp2\b2.txt"};
    
        var test = new List<string>();
        var common = paths[0].Split('\\').TakeWhile ( segment => 
        {
            test.Add ( segment );
            return paths.All ( path => path.StartsWith ( String.Join ("\\", test )  + "\\") ) ;
        } );
    
        Console.WriteLine ( String.Join ("\\", common ) );
    }
    
    0 讨论(0)
  • 2021-01-17 16:32

    The selected solution does not work properly if one of the paths is exactly the directory name that should be returned. I think there should be:

    from len in Enumerable.Range(0, matchingNames.Min(s => s.Length) + 1).Reverse()

    0 讨论(0)
提交回复
热议问题