0

First text file looks like this:

eu
alps
nl
de
sp
fr
gr
it
pl
scan

Second text file looks like this:

Europe
Alps
Benelux
Germany
Spain & Portugal
France
Greece
Italy
Poland
Scandinavia

I want to read both text files and create a new text file in this format:

Code = eu
Country = Europe
Code = alps
Country = Alps
Code = nl
Country = Benelux

And so on for the rest in this format.

What i did so far is reading the lines from each file: but not sure how to continue.

IEnumerable f1 = File.ReadLines(@"c:\temp\txt1");
IEnumerable f2 = File.ReadLines(@"c:\temp\txt2");
sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
moshe ralf
  • 489
  • 3
  • 12
  • 21
  • 1
    Are you sure about the inputs, Will it always in the same order? – sujith karivelil Feb 14 '17 at 01:08
  • 2
    Why was this question downvoted? It seems to be on-topic, it's clearly written, and it shows some amount of effort on the part of the author. – Tanner Swett Feb 14 '17 at 02:18
  • @TannerSwett : was wondering the same thing too, I have seen some crap questions, getting 6 points, and some good questions getting downvoted. The short of it is, if you have friends on SE, no matter what a pile of garbage you write you get upvoted, and if not then hello downvotes. I actually like this question so I upvoted it too, but up or down vote at times has nothing to do with quality, I have seen the same issue on Math SE as well. I have given up trying to ask the question that you ask, just do my little bit to help. – jimjim Feb 14 '17 at 02:47
  • @un-lucky : if it is possible to write something that doesn't assume the order of inputs that will be better than relying on it. – jimjim Feb 14 '17 at 02:49
  • 1
    All the answers are missing the most important part of programming, that is to make meaningful structures for the context at hand, just reading and manipulating string and file streams is not programming, that is hacking. A good answer should put the values into a meaningful structure. – jimjim Feb 14 '17 at 02:51
  • A lot of time has passed, and "Update the question so it focuses on one problem only" does not make any sense... I agree that title is almost totally wrong, because he does not want to append the files, as title suggests. But he was understood, because he has at least 3 working answers... – Marcelo Scofano Diniz Nov 30 '20 at 04:34

5 Answers5

3

Zip corresponding lines of two files, select code and country strings and flatten strings array before writing it to file:

File.WriteAllLines(@"c:\temp\txt3",
   f1.Zip(f2, (l1,l2) => new[] { $"Code = {l1}", $"Country = {l2}" }).SelectMany(a => a));

Don't forget to use IEnumerable<string> type for f1 and f2. You can also produce single string:

File.WriteAllLines(@"c:\temp\txt3",
   f1.Zip(f2, (l1,l2) => $"Code = {l1}{Environment.NewLine}Country = {l2}" ));

Output:

Code = eu
Country = Europe
Code = alps
Country = Alps
Code = nl
Country = Benelux
Code = de
Country = Germany
Code = sp
Country = Spain & Portugal
Code = fr
Country = France
Code = gr
Country = Greece
Code = it
Country = Italy
Code = pl
Country = Poland
Code = scan
Country = Scandinavia

= Try Me =

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • `Zip` is fairly elegant, but in this case I also think it might be a bit overkill. I think un-lucky's answer is simpler and more to the point. – Abion47 Feb 14 '17 at 01:56
  • 1
    i believe the use of `Zip` is a good solution here, as it also considers the case when the `IEnumerable` items dont match in count. see http://stackoverflow.com/a/5122767/3956100 – Niklas Feb 14 '17 at 05:25
  • @Abion47 performance boost is never overkill - zip enumerates two iterators instead of dumping all file contents into arrays or lists. You can eliminate array of strings creation, but not zip – Sergey Berezovskiy Feb 14 '17 at 08:08
  • Except you are also using the `SelectMany` after the `Zip` which involves another round of iteration. I also can't see any LINQ solution being more performant than the single for-loop solution that un-lucky provided. – Abion47 Feb 14 '17 at 10:18
  • @Abion47 I don't see any SelectMany here `f1.Zip(f2, (l1,l2) => $"Code = {l1}{Environment.NewLine}Country = {l2}" )`. Did you do some performance tests of these solutions? I bet LINQ will win – Sergey Berezovskiy Feb 14 '17 at 10:53
1

Try this:

List<string> codeList = File.ReadLines(@"c:\temp\txt1").ToList();
List<string> nameList = File.ReadLines(@"c:\temp\txt2").ToList();

StringBuilder codeNameBuilder = new StringBuilder();

for (int i = 0; i < codeList.Count; i++)
{
    codeNameBuilder.AppendFormat("Code = {0} \n Country = {1}", codeList[i], nameList[i]);
}

System.IO.File.WriteAllText(@"c:\temp\txtOutput.txt", codeNameBuilder.ToString());
sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
0

I would do this:

string[] f1 = File.ReadAllLines(@"c:\temp\txt1");
string[] f2 = File.ReadAllLines(@"c:\temp\txt2");
string[] f3 = new string[Math.Min(f1.Length, f2.Length)];

for (int i = 0; i < f3.Length; i++)
     f3[i] = "Code = " + f1[i] + "\nCountry = " + f2[i] +"\n";
File.WriteAllLines(@"c:\temp\txt3", f3);
Everyone
  • 1,751
  • 13
  • 36
0

Try this:

        string CodePath = Environment.CurrentDirectory + @"\Code.txt";
        List<string> Codes = File.ReadLines(CodePath).ToList();

        string CountryPath = Environment.CurrentDirectory + @"\Country.txt";
        List<string> Countries = File.ReadLines(CountryPath).ToList();

        string result = string.Empty;
        int length = Math.Min(Codes.Count, Countries.Count);
        for (int i = 0; i < length; i++)
        {
            result += "Code = " + Codes[i] + Environment.NewLine + "Country = " + Countries[i] + Environment.NewLine;
        }

        string OutPath = Environment.CurrentDirectory + @"\out.txt";
        File.WriteAllText(OutPath, result);
0

Method 1 (3 Arrays)

Create two arrays and then a third array to store the concatenated strings:

var codes = File.ReadAllLines( "Codes.txt" );
var countries = File.ReadAllLines( "Countries.txt" );

var lines = new List<string>( codes.Length );
for( int i = 0; i < codes.Length; i++ ) {
   lines.Add( $"Code = {codes[ i ]}" + Environment.NewLine + $"Country = {countries[ i ]}" );
}

File.WriteAllLines( "Result.txt",  lines);

Method 2 (2 Arrays so less memory)

If you do not want the third array due to memory consumption, then you can use one of the array you already have and store the concatenated strings in them:

var codes = File.ReadAllLines( "Codes.txt" );
var countries = File.ReadAllLines( "Countries.txt" );

for( int i = 0; i < codes.Length; i++ ) {
   codes[i] = $"Code = {codes[ i ]}" + Environment.NewLine + $"Country = {countries[ i ]}";
}

File.WriteAllLines( "Result.txt", codes );

This is the best option because it is the best of both worlds: less memory and only 3 IO operations (2 reads, 1 write).


Method 3 (1 Array so lesser memory)

This technique will read all countries into memory and then read one line from the codes file into memory, write it to the destination file, and then read another line from the codes file. So at any given time, there is only one code in memory. This is achieved using File.ReadLines.

var countries = File.ReadAllLines( "Countries.txt" );
int i = 0;
File.WriteAllLines( "Result2.txt", File.ReadLines( "Codes.txt" )
   .Select( x => $"Code = {x}" + Environment.NewLine + $"Country = {countries[ i++ ]}" ) );
CodingYoshi
  • 25,467
  • 4
  • 62
  • 64