1

I have a List that contains all the remote Path I need

List<string> remotePath = MyTableWithRemotePath.Select(i => i.ID_SERVER_PATH).ToList();

I have a string which is the server I'm finding.

string remotePath = "Path I'm looking for";

I have to find which is the path of the list which match better with the one I'm looking for.

I tried with this but it doesn't work

var matchingvalues = remotePath.FirstOrDefault(stringToCheck => stringToCheck.Contains(remotePath));

Any suggestions?

EDIT

Example:

I have to find the best match for this path: C:\\something\\location\\

This is my List:

- C:\\something\\location\\XX\\
- C:\\something\\location2\\YY\\
- C:\\something\\location3\\AA\\
- C:\\something\\location4\\CS\\

The result have to be the first element:

C:\\something\\location\\directory\\

Galma88
  • 2,398
  • 6
  • 29
  • 50
  • 4
    Could you explain "better match"? Some examples maybe? – Hans Kesting Sep 22 '15 at 14:17
  • What do you mean by "I have to find which is the path of the list which match better with the one I'm looking for". Are you just trying to do a partial match on your string, looking for something with the most matching characters? If so, perhaps you could break up `PathImLookingFor` into separate directories and find items in your list contain those directories, in order by most matches to least. – sab669 Sep 22 '15 at 14:17
  • @sab669 exactly. That's it – Galma88 Sep 22 '15 at 14:18
  • 1
    You mean like the SQL `LIKE` operator? Or something more like google that'll find `food` if you type `foopd`? – Thomas Ayoub Sep 22 '15 at 14:24
  • @Thomas Take 3 strings: the first two are the strings we're inspecting and the third string is the one we want to find the closest match to. `"C:\some\directory\is\here\"`, `"C:\some\directory\over\here"` are two values in `remotePath`. `"\directory\is\"` is the string we want to find the closest match to. So while both of the first two strings contain `directory` in their path, the first one is the "better match" since it contains more matching directories. – sab669 Sep 22 '15 at 14:38
  • and will you be looking for `+direktorii\ise` or will you have formated data with no naming error? – Thomas Ayoub Sep 22 '15 at 14:40
  • I've edited my post with an example – Galma88 Sep 22 '15 at 15:06
  • @Galma88 please take a look, I changed my code based on your more explanation of your code. – Vlad Bezden Sep 22 '15 at 17:48
  • Possible duplicate of [string comparison with the most similar string](http://stackoverflow.com/questions/5861718/string-comparison-with-the-most-similar-string) – Raedwald Jan 23 '16 at 17:28

3 Answers3

2

I'd say instead of:

string dir = @"some\\path\\im\\looking\\for";

Break that up into an array for each path.

string[] dirs = new string[n] { "some", "path", "im", "looking", "for" };

Then iterate over your list, checking each item in the array as well. Each time there's a match, add it to another collection with the key (the full path) and the value (the number of matches).

for (int i = 0; i < remotePath.Count; i++)
{
    int counter = 0;

    for (int j = 0; j < dirs.Length; j++)
    {
        if (remotePath[i].Contains(dirs[j])
            counter++;
    }

    if (counter > 0)
        someStringIntDictionary.Add(remotePath[i], counter);
}

In regards to the final task of determining which is the "best match", I'm honestly not sure exactly how to do it but searching Google for C# find dicitonary key with highest value gave me this:

https://stackoverflow.com/a/2806074/1189566

This answer might not be the most efficient, with nested looping over multiple collections, but it should work.

I'd like to point out this is succeptible to inaccuracies if the filename or a subdirectory shares part of a name with something in dirs. So using the first item in the array, "some", you might run into an error with the following scenario:

"C:\\something\\location\\directory\\flibflam\\file.pdf"

something would incorrectly match to some, so it might not actually be a valid match. You'd probably want to check the adjacent character(s) to the directory in the actual path and make sure they're \ characters.

Community
  • 1
  • 1
sab669
  • 3,984
  • 8
  • 38
  • 75
0
var remotePaths = new List<string>
{
    @"C:\something\location\directory\",
    @"C:\something\location2\directory\",
    @"C:\something\location3\directory\",
    @"C:\something\location4\directory\"
};

var remotePath = @"C:\something\location\directory\";


var result = remotePaths
    .Select(p => new { p, mathes = p.Split('\\').TakeWhile((x, i) => x == remotePath.Split('\\')[i]).Count()})
    .OrderByDescending(p => p.mathes)
    .First().p;

Result:

C:\something\location\directory\

The code goes through each directory creates parse it and creates subdirectories for each one, then compares each subdirectory with remotePath subdirectory. In the end it takes the first one that has most number of matches.

Vlad Bezden
  • 83,883
  • 25
  • 248
  • 179
  • What do you mean the same matches. Code returns exactly what you asked in your questions. Can you please elaborate what exactly doesn't work? – Vlad Bezden Sep 23 '15 at 12:43
0

At the end I did it in this way and perfectly works:

    var bestPath  = remotePaths.OrderByDescending(i => i.ID_FILE_PATH.Length)
                               .ToList()
                               .FirstOrDefault(i => rootPath.StartsWith(i.ID_FILE_PATH, StringComparison.InvariantCultureIgnoreCase));
Galma88
  • 2,398
  • 6
  • 29
  • 50
  • The `ToList` is redundant. – Tim Schmelter Sep 25 '15 at 14:01
  • @TimSchmelter No, without ToList() I got exception. – Galma88 Sep 25 '15 at 14:08
  • Not possible if `remotePaths` is a `List` as you've stated. But since `string` has no property `ID_FILE_PATH` it must be something different. I guess it's a database object and the linq provider doesn't support `StartsWith` with the overload `StringComparison`. That's why you've created an in-memory `List` from all records. I hope you have enough memory. You could use `rootPath.ToUpper().StartsWith(i.ID_FILE_PATH.ToUpper())` instead. – Tim Schmelter Sep 25 '15 at 14:14