Galma88
Galma88

Reputation: 2546

Get the more similar string from a list

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\\

Upvotes: 1

Views: 2134

Answers (3)

Galma88
Galma88

Reputation: 2546

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

Upvotes: 0

Vlad Bezden
Vlad Bezden

Reputation: 89547

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.

Upvotes: 0

sab669
sab669

Reputation: 4104

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.

Upvotes: 2

Related Questions