Question

I can currently use Enumerable except to get the difference of two strings.

My goal is to trim temporary the start of the string by 20 characters of both string[] when checking for the file1Lines.Except(file2Lines) and when it returns a value, I want it to be the complete string[] again

I need to do this because I want to compare all the DIRECTORY of the strings that are in the first but not in the second and save the complete line (with the date time like my string sample)

If I can't use Enumerable Except to achieve this, is there another option?

Here is a sample string that I use:

2009-07-14 04:34:14 \CMI-CreateHive{6A1C4018-979D-4291-A7DC-7AED1C75B67C}\Control Panel\Desktop

Here is my sample code:

        string[] file1Lines = File.ReadAllLines(textfile1Path);
        string[] file2Lines = File.ReadAllLines(textfile2Path);

        // This currently only gets a non-trimmed string, but if i trim it
        // it will return the trimmed string, I want it to return the full string again
        IEnumerable<String> inFirstNotInSecond = file1Lines.Except(file2Lines);
        IEnumerable<String> inSecondNotInFirst = file2Lines.Except(file1Lines);

Thank you and have a nice day

Was it helpful?

Solution

You could use the overload of Except that takes a IEqualityComparer. The comparer can then be written to only compare strings after the first 20 characters. This way the Except will compare the strings after the first 20 characters, but will not actually truncate the values returned.

public class AfterTwenty : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        if (x == null)
        {
            return y == null;
        }

        return x.Substring(20) == y.Substring(20);
    }

    public int GetHashCode(string obj)
    {
        return obj == null ? 0 : obj.Substring(20).GetHashCode();
    }
}

Then you can call Except like this.

   var comparer = new AfterTwenty();
   var inFirstNotInSecond = file1Lines.Except(file2Lines, comparer);
   var inSecondNotInFirst = file2Lines.Except(file1Lines, comparer);

OTHER TIPS

You could use an anonymous type and Enumerable.Join:

var lines1 = file1Lines
    .Select(l => new { Line = l, Firstpart = l.Split('\\')[0].Trim() });
var lines2 = file2Lines
    .Select(l => new { Line = l, Firstpart = l.Split('\\')[0].Trim() });

var inFirstNotInSecond = lines1.Select(x => x.Firstpart)
    .Except(lines2.Select(x => x.Firstpart));
var inSecondNotInFirst = lines2.Select(x => x.Firstpart)
    .Except(lines1.Select(x => x.Firstpart));

IEnumerable<String> inFirstNotInSecondLines =
    from l1 in lines1
    join x1 in inFirstNotInSecond on l1.Firstpart equals x1
    select l1.Line;
IEnumerable<String> inSecondNotInFirstLines =
     from l2 in lines2
     join x2 in inSecondNotInFirst on l2.Firstpart equals x2
     select l2.Line;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top