3

I've got two files

"Database.txt" contains the following names:

  1. Dog
  2. Cat
  3. Mouse
  4. Panda
  5. Bear

"Slave.txt" contains the following names:

Cat
Panda

I want to compare the "Slave.txt" with "Database.txt" and create third file with:

2. Cat  
4. Panda  

(Cat and Panda from Slave.txt find in Database.txt)

My code:

static void Main(string[] args)
    {
        String directory = @"C:\Users\user\Desktop\";
        String[] linesA = File.ReadAllLines(Path.Combine(directory, "Database.txt"));
        String[] linesB = File.ReadAllLines(Path.Combine(directory, "Slave.txt"));
        IEnumerable<String> onlyB = linesB.Intersect(linesA);
        File.WriteAllLines(Path.Combine(directory, "Result.txt"), onlyB);
    }

works only on Database.txt structure like:

Dog
Cat
Mouse
Panda
Bear

without line numbers. Is there somethink instead .Intersect to find only part of string, not full string?

3
  • 2
    Do you want to match also "12. Blue Panda" with "Panda"? Commented Apr 22, 2016 at 12:43
  • Just write a loop. Or if you really want to use linq, a .Where(predicate func) Commented Apr 22, 2016 at 12:46
  • As a second parameter the function .intersect allows you to put in a customer equalitycomparer on which you can decide how to compare your objects. Using this equality comparer you can make an equasion on string.contains(otherString) for example. Or even easier: Use jasonw's suggestion Commented Apr 22, 2016 at 12:49

3 Answers 3

4

A very simple approach is with Any from Linq. It is only checking if any part of a line in B is contained in any line of A no matter the case.

var onlyB = linesA.Where(a => linesB.Any(b => a.ToLower().Contains(b.ToLower())));

Note: Updated to shows lines from A instead of lines from B.

Sign up to request clarification or add additional context in comments.

2 Comments

It still shows me in Result.txt: "Cat Panda" not "2. Cat 4. Panda"
Sorry, must have misread your question. I thought you wanted the B lines instead of the A lines, but no big deal. Just updated answer to account for that.
1

you can use Linq like this:

static void Main(string[] args)
    {
        String directory = @"C:\Users\user\Desktop\";
        String[] linesA = File.ReadAllLines(Path.Combine(directory, "Database.txt"));
        String[] linesB = File.ReadAllLines(Path.Combine(directory, "Slave.txt"));
        IEnumerable<String> onlyB = linesA.Where(x=>linesB.Contains(x.Substring(x.IndexOf(". "+1))));
        File.WriteAllLines(Path.Combine(directory, "Result.txt"), onlyB);
    }

2 Comments

Try this again I changed somethings
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll. Additional information: StartIndex cannot be lower then zero.
0

Here's a test method that I wrote and tested:

private string[] Matcher()
{
    string[] file1 = { "1. Dog","2. Cat","3. Mouse","4. Panda","5. Bear" };
    string[] file2 = { "Cat", "Panda" };
    string[] file3 = file1.Where(d => {
        foreach(string matcher in file2)
        {
            if(Regex.Match(d, @"^\d+\.\s+"+matcher + "$").Length > 0)
            {
                return true;
            }
        }
        return false;
    }).ToArray<string>();            

    return file3;
}

I suppose you have line or item numbers before the records on file1. This will try to match for : a number combination, a dot and the desired values with a regular expression, and when it matches an element on the list, it'll take that element to the file3 array.

And it will discard Sabre Cat when you are searching only for Cat.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.