2

I have the following program, What i am trying to do is join a list of names I have from a 2 text files,In the first text file i have First names, in the secont last names, I am trying to join them. Further then that I am trying to make a list of all combinations of the files ie, First names are mark and mike, last names are wilson and watson, I want to make mike watson and mike wilson

    TextReader sr = new StreamReader(textBox1.Text);
        TextReader sr2 = new StreamReader(textBox2.Text);
        string contents = sr.ReadToEnd();
        string contents2 = sr2.ReadToEnd();
        string[] myArray = { contents };
        string[] myArray2 = { contents2 };
        foreach (string element1 in myArray)
        {
            foreach (string element2 in myArray2)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                sb.Append(element1);
                sb.Append(" " + element2);
                Debug.WriteLine(sb.ToString());

                string str = sb.ToString();
                Debug.WriteLine(str);

                //MessageBox.Show(sb.ToString);
            }
        }

The end result should be , Mike Smith from file1 : mike, file2 : smith

thanks for the help

Using a comination of the above answers I came up with this answer, the '\r' when splitting the text files was critical as the text was read from windows 2003 (I am not sure on win 7 or 2008 what the results would be) Using the inbuilt array was good but I got completly different results when trying to run it from the filesystem, adding the '\r' fixed that Please see this post

In C#, what's the difference between \n and \r\n?

TextReader sr = new StreamReader(textBox1.Text);
        TextReader sr2 = new StreamReader(textBox2.Text);
        string contents = sr.ReadToEnd();
        string contents2 = sr2.ReadToEnd();
        string[] firstNames = contents.Split(new Char[] { '\r','\n',' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
        string[] lastNames = contents2.Split(new Char[] { '\r','\n',' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
        var fullnames =
                    from fn in firstNames
                    from ln in lastNames
                    select new { Fullname = fn + " " + ln };

        foreach (var person in fullnames)
        {
            Debug.WriteLine(person.Fullname);
            //MessageBox.Show(person.Fullname);
        }
Community
  • 1
  • 1
user1388425
  • 117
  • 2
  • 8
  • I dont think that i made it clear at the begining, I have 2 lists of names, one list first names like "Mark" secont list is last names "Watson" and "Wilson" I am trying to make a text file with all the iterations of mark, ie Mark Watson , Mark Wilson etc – user1388425 May 11 '12 at 02:09

8 Answers8

4

LINQ

This would join first firstname with first lastname

string[] joinednames = myArray.Zip(myArray2, (x, y) => x + " " + y).ToArray();

If you want to join first firstname with all lastname and second firstname with all lastnames and so on then use this

string[] joinednames = myArray.Select(x => myArray2.Select(y => 
                       x + " " + y)).SelectMany(x => x).ToArray();

Suppose first list contains firstnames

"Mark", "Marry"

and second list contains lastnames

"Watson" and "Wilson".

First Snipppet will give

"Mark Watson", "Marry Wilson"

Second Snippet will give

"Mark Watson", "Mark Wilson", "Marry Watson", "Marry Wilson"

I think second snippet is what you need.

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
1

Your current code is close.

TextReader sr = new StreamReader(textBox1.Text); 
TextReader sr2 = new StreamReader(textBox2.Text); 

string contents = sr.ReadToEnd(); 
string contents2 = sr2.ReadToEnd(); 

string[] myArray = contents.Split(new Char [] {' ', ','}, StringSplitOptions.RemoveEmptyEntries); 
string[] myArray2 = contents2.Split(new Char [] {' ', ','}, StringSplitOptions.RemoveEmptyEntries); 
System.Text.StringBuilder sb = new System.Text.StringBuilder();

var joinednames = myArray.Zip(myArray2, (x, y) => x + " " + y).ToList();

foreach (string str in joinednames)
{
    Debug.WriteLine(str);
}

You should probably have some additional separators to go between the names.

Edit: I combined my answer with Nikhil's and after doing some testing in VS.

mgnoonan
  • 7,060
  • 5
  • 24
  • 27
1

I agree with mgnoonan that your main problem is that you're not getting your list of names parsed out into your array correctly. Go with his method for getting the names into an array. But then, once you've got them there, I like the elegance of Nikhil's LINQ solution for combining the two arrays. Use them both.

Edit: Example below

TextReader sr = new StreamReader(textBox1.Text); 
TextReader sr2 = new StreamReader(textBox2.Text); 

string contents = sr.ReadToEnd(); 
string contents2 = sr2.ReadToEnd(); 

string[] myArray = contents.Split(new Char [] {' ', ','}); 
string[] myArray2 = contents2.Split(new Char [] {' ', ','}); 

string[] joinednames = myArray.Zip(myArray2, (x, y) => x + " " + y).ToArray();

foreach(string element in joinednames)
{
    Debug.WriteLine(element);
}
jdmcnair
  • 1,305
  • 15
  • 33
  • 1
    You need to combine mgnoonan's method of getting the names actually into the arrays with Nikhil's LINQ statement. Your original code puts the entire text of the file into a single array element. Mgnoonan's code shows you how to parse the names out. Once you've got the elements in the array, the LINQ statement will work. – jdmcnair May 11 '12 at 01:56
1

This answer is only based on the comment that you have made to your question. Based on your comment, if you are looking to create all possible combinations of the arrays, here is a solution without LINQ

string[] firstNames = {"Mark", "Mike" };
string[] lastNames = {"Watson", "Wilson" };
IList<string> allNameCombinations = new List<string>();

foreach (string firstname in firstNames)
{
    foreach (string lastname in lastNames)
         allNameCombinations.Add(firstname + " " + lastname);
}

string[] allNames = allNameCombinations.ToArray();

output array will have the following elements

Mark Watson
Mark Wilson
Mike Watson
Mike Wilson
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
Prashanth Thurairatnam
  • 4,353
  • 2
  • 14
  • 17
0

While other answers are helpful, they do not explain where you went wrong. The problem with your original code is these statements:

string[] myArray = { contents }; 
string[] myArray2 = { contents2 }; 

The first statement creates an array with one element; that element is a reference to the same string referenced by the contents variable. Similarly, myArray2 is an array with a single element equal to contents2.

Create the arrays by splitting on the line separator characters:

string[] myArray = contents.Split(new Char [] {'r', 'n'}, StringSplitOptions.RemoveEmptyEntries);    
string[] myArray2 = contents2.Split(new Char [] {'r', 'n'}, StringSplitOptions.RemoveEmptyEntries); 

and combine them as Nikhil Agrawal suggests; however, you may find query comprehension syntax easier to, well, comprehend:

IEnumerable<string> fullNames = 
    from firstName in myArray
    from lastName in myArray2
    select firstName + " " + lastName

or, to reverse the order of the product:

IEnumerable<string> fullNames = 
    from lastName in myArray2
    from firstName in myArray
    select firstName + " " + lastName

Or, if you prefer not to use linq:

foreach (string firstName in myArray)
    foreach (string lastName in myArray2)
    {
        string fullName = firstName + " " + lastName;
        // do something with the fullName here
    }
phoog
  • 42,068
  • 6
  • 79
  • 117
  • First names are mark and mike, last names are wilson and watson, I want to make mike watson and mike wilson – user1388425 May 11 '12 at 02:01
  • @user1388425 and what happens when you use the approach outlined above? – phoog May 11 '12 at 02:52
  • @user1388425 I updated my answer with a Linq "query-comprehension" syntax solution, which may be easier to understand than the method-chain syntax answers that others have offered. – phoog May 11 '12 at 14:11
0

You need to read entries from the files better (reads more than one line, and more than one entry per line, space or comma separated):

var firsts = File.ReadAllLines(textBox1.Text).SelectMany(n => n.Split(new Char [] {' ', ','}));
var lasts = File.ReadAllLines(textBox2.Text).SelectMany(n => n.Split(new Char [] {' ', ','}));

Then you can do as the other answers suggest:

var fullNames = firsts.Zip(lasts, (f, l) => f + " " + l).ToArray();

Note: Ensure you import LINQ with using System.Linq;

yamen
  • 15,390
  • 3
  • 42
  • 52
  • First names are mark and mike, last names are wilson and watson, I want to make mike watson and mike wilson – user1388425 May 11 '12 at 02:01
  • 1
    OK seriously you don't need to make the same comment to every person. Most of the answers are very similar. Try some and report results if it's not what you want. Saying "I don't know LINQ" is not a valid answer since the LINQ solutions are far easier to understand and maintain than your original code. – yamen May 11 '12 at 02:05
  • The LINQ answer does not work, I tried the code and it showed a list but it did not give the correct result, Mike mark Watson Wilson is the result – user1388425 May 11 '12 at 02:11
  • 1
    You tried the code I've got above there? All of it? If so, show us the full contents of your file. It's tested and it works. – yamen May 11 '12 at 02:19
0

Reading your question's comment, you want to list all the possibilities of combining firstname and lastname, isn't it?

You can try this:

var fullnames = 
        from fn in firstNames
        from ln in lastNames
        select new { Fullname = fn + " " + ln };

foreach(var person in fullnames) {
    Console.WriteLine (person.Fullname);
}

Complete code:

using System;
using System.Collections.Generic;
using System.Linq;

public class Test
{
        public static string[] firstNames = {"Mark", "Mike" };
        public static string[] lastNames = {"Watson", "Wilson"};

        public static void Main (string[] args)
        {

                var fullnames = 
                        from fn in firstNames
                        from ln in lastNames
                        select new { Fullname = fn + " " + ln };

                foreach(var person in fullnames) {
                     Console.WriteLine (person.Fullname);
                }

      }
}

Output:

Mark Watson
Mark Wilson
Mike Watson
Mike Wilson

Demo code: http://ideone.com/ei6vh

Michael Buen
  • 38,643
  • 9
  • 94
  • 118
0

There's something wrong with your code on these lines:

string contents = sr.ReadToEnd();
string contents2 = sr2.ReadToEnd();

// arrays don't automatically split string content
string[] myArray = { contents };
string[] myArray2 = { contents2 };

You should do these:

string contents = sr.ReadToEnd();
string contents2 = sr2.ReadToEnd();

// arrays don't automatically split file content
string[] myArray = contents.Split('\n');
string[] myArray2 = contents2.Split('\n');

Or better yet, split it on reader:

string[] myArray = sr.ReadToEnd().Split('\n');
string[] myArray2 = sr.ReadToEnd().Split('\n');

Note that some textfiles' line separator are not consistent, some uses a combination of \r\n (most text files coming from windows apps), some just uses \n only, I haven't seen a text file using \r only for line separator.

Do this instead:

string[] myArray = 
    sr.ReadToEnd().Split (new[]{"\r\n", "\n", "\r"}, StringSplitOptions.None);

string[] myArray2 = 
    sr.ReadToEnd().Split (new[]{"\r\n", "\n", "\r"}, StringSplitOptions.None);
Michael Buen
  • 38,643
  • 9
  • 94
  • 118