How to merge values of two lists together - c#

For example I have:
public static List<int> actorList = new List<int>();
public static List<string> ipList = new List<string>();
They both have various items in.
So I tried joining the values (string and int) together using a foreach loop:
foreach (string ip in ipList)
{
foreach (int actor in actorList)
{
string temp = ip + " " + actor;
finalList.Add(temp);
}
}
foreach (string final in finalList)
{
Console.WriteLine(finalList);
}
Although looking back at this, this was pretty stupid and obviously will not work, as the first forloop is nested.
My expected values for finalList list:
actorListItem1 ipListItem1
actorListItem2 ipListItem2
actorListItem3 ipListItem3
and so on..
So the values from the two lists are concatenated with each other - corresponding of their position in the lists order.

Use ZIP function of LINQ
List<string> finalList = actorList.Zip(ipList, (x,y) => x + " " + y).ToList();
finalList.ForEach(x=> Console.WriteLine(x)); // For Displaying
OR combine them in one line
actorList.Zip(ipList,(x,y)=>x+" "+y).ToList().ForEach(x=>Console.WriteLine(x));

What about some functional goodness?
listA.Zip(listB, (a, b) => a + " " + b)

Assuming you can use .NET 4, you want to look at the Zip extension method and the provided example:
int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
// The following example concatenates corresponding elements of the
// two input sequences.
var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second);
foreach (var item in numbersAndWords)
Console.WriteLine(item);
Console.WriteLine();
In this example, because there is no corresponding entry for "4" in words, it is omitted from the output. You would need to do some checking to make sure the collections are the same length before you start.

Loop over the indexes:
for (int i = 0; i < ipList.Count; ++i)
{
string temp = ipList[i] + " " + actorList[i];
finalList.Add(temp);
}
You may also want to add code before this to verify that the lists are the same length:
if (ipList.Count != actorList.Count)
{
// throw some suitable exception
}

for(int i=0; i<actorList.Count; i++)
{
finalList.Add(actorList[i] + " " + ipList[i]);
}

Related

How to pick items from list of lists

I need a bit of help. I have a list of 5k elements that is a path to files. I split the list into five smaller lists. My problem is how can I loop over the list of lists and pick the elements from all five at the same iteration.
Sample of code.
The source list:
List<string> sourceDir = new List<string>(new string[] { "C:/Temp/data/a.txt", "C:/Temp/data/s.txt", "C:/Temp/data/d.txt", "C:/Temp/data/f.txt", "C:/Temp/data/g.txt", "C:/Temp/data/h.txt", "C:/Temp/data/j.txt", "C:/Temp/data/k.txt", "C:/Temp/data/l.txt", "C:/Temp/data/z.txt"});
Splitting the list into smaller list:
public static List<List<T>> Split<T>(IList<T> source)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / 2)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
Result:
var list = Split(sourceDir);
As result in the variable list, I get five lists. How can I now access items from all lists at one iteration for further processing?
Something like:
foreach (string fileName in list[0])
{
foreach (string fileName1 in list[1])
{
foreach (string fileName2 in list[2])
{
foreach (string fileName3 in list[3])
{
foreach (string fileName4 in list[4])
{
//have items from all lists
Console.WriteLine("First name is: " + fileName);
Console.WriteLine("Second name is: " + fileName1);
Console.WriteLine("Third name is: " + fileName2);
Console.WriteLine("Fourth name is: " + fileName3);
Console.WriteLine("Fift name is: " + fileName4);
break;
}
break;
}
break;
}
break;
}
continue;
}
the above foreach loop is just to get an idea of what I need.
Multithreading on file IO operations is not always a good choice. You add the overhead for thread switches, but the disk access is bound to other considerations. Look here for example
Does multithreading make sense for IO-bound operations?
However, just to answer your question, you can use a standard for loop instead of all those foreach, the only thing you need to take care is the case when the sublists don't have the same number of elements. (files number not exactly divisible by 5)
int maxIndex = Math.Max(list[0].Count,
Math.Max(list[1].Count,
Math.Max(list[2].Count,
Math.Max(list[3].Count, list[4].Count))));
for (int x = 0; x < maxIndex; x++)
{
string item0 = x < list[0].Count ? list[0][x] : "No item";
string item1 = x < list[1].Count ? list[1][x] : "No item";
string item2 = x < list[2].Count ? list[2][x] : "No item";
string item3 = x < list[3].Count ? list[3][x] : "No item";
string item4 = x < list[4].Count ? list[4][x] : "No item";
Console.WriteLine("First name is: " + item0);
Console.WriteLine("Second name is: " + item1);
Console.WriteLine("Third name is: " + item2);
Console.WriteLine("Fourth name is: " + item3);
Console.WriteLine("Fifth name is: " + item4);
}

Merging two items into one inside a List<string> in C#

I have a List<string> with the name data with this items:
{ A101, Plans, A102, Elev/Sec, A103, Unnamed }
foreach (string item in data)
{
data1.Add(item + item);
}
I wanted the output to be like this:
A101 Plans
A102 Eleve/Sec
A103 Unnamed
But the output is:
A101 A101
Plans Plans
A102 A102
Eleve/Sec Eleve/Sec
A103 A103
Unnamed Unnamed
How can I fix this problem?
It's not easy to do with a foreach; you'd have to remember the previous element and put the combination into a list when the memory is not blank, then blank the memory
It's easier with a straight for that goes in jumps of two
for(int i=0; i < list.Length; i+=2){
Console.WriteLine(list[i] + " " + list[i+1]);
}
With a foreach it's like:
string x = null;
foreach(var item in list){
if(x == null){
x = item;
} else {
Console.WriteLine(x + " " + item);
x = null;
}
}
x flipflops between being null and something. When it is null, the item is remembered, when it is something the output is the "previous item i.e. x plus the current item"

Using select information from array

I have a string array of the form [a b, a b, a b,...] and I want to create a new array of just the b values. I have tried a .split(" ") but it keeps coming up with an index outside the bounds of the array error.
for (int sequence = 0; sequence < FileIndex.Length; sequence++)
{
string[] SplitIndex = FileIndex[sequence].Split(' ');
sequence++;
WriteLine(SplitIndex[sequence]);
}
for (int sequence = 0; sequence < FileIndex.Length; sequence++)
{
string[] SplitIndex = FileIndex[sequence].Split(' ');
sequence++;
WriteLine(SplitIndex[1]);
}
Once you split, in the SplitIndex you will have 2 elements: "a" and "b". If you want to access "b" you will have to use SplitIndex[1]. You are currently using SplitIndex[sequence]
Also, you have sequence++ twice. One in the for statement, and one inside the loop. You should remove it from the loop.
You could also use LINQ here:
using System.Linq;
...
var stringArray = new string[] { "a b", "a b", "a b" };
var result = stringArray
.Select(str => str.Split(' ').Last())
.ToArray();
Console.WriteLine("{ " + string.Join(", ", result) + " }");
// { b, b, b }
Explanation:
Select every element in the array with Enumerable.Select()
Split each string with String.Split() and take the last element with Enumerable.Last(). You could also just index the second element with [1] here as well.
Convert the result to an array with List.ToArray(). Optionally you could just leave the result as an IEnumerable<string> as well.
for way
Remove sequence++;
Change WriteLine(SplitIndex[sqequence]); to WriteLine(SplitIndex[1]);
for (int sequence = 0; sequence < FileIndex.Length; sequence++)
{
string[] SplitIndex = FileIndex[sequence].Split(' ');
//sequence++;
WriteLine(SplitIndex[1]);
}
Linq way
//Note: no error handling
var bees = FileIndex.Select(fi => fi.Split(' ')[1]);
You can add error handling
var bees = test.Select(fi => fi.Split(' ', StringSplitOptions.RemoveEmptyEntries).Skip(1).FirstOrDefault() ?? "'No b!'" );
Test
var test = new string[] { "a a", "a b", "a c", "a ", "" };
var bees = test.Select(fi => fi.Split(' ', StringSplitOptions.RemoveEmptyEntries).Skip(1).FirstOrDefault() ?? "'No b!'" );
Console.WriteLine(string.Join(" ", bees));
a b c 'No b!' 'No b!'

Three combination of dimension array in C#?

How do I create three combinations of dimension array in C#?, I am getting error message
index was outside of the bounds of the array.
foreach (XmlNode RegexExpression in XmlDataAccess.GetElementList(RefFile, "//regex"))
{
xRefList.Add(RegexExpression.InnerText);
}
foreach (XmlNode RegexExpression in XmlDataAccess.GetElementList(RefFile, "//word"))
{
WordList.Add(RegexExpression.InnerText);
}
foreach (XmlNode RegexExpression in XmlDataAccess.GetElementList(RefFile, "//title"))
{
TitleList.Add(RegexExpression.InnerText);
}
ArrayList xRefResult = MainDocumentPart_Framework.getReferenceContent(FileName, xRefList);
ArrayList TitleResult = MainDocumentPart_Framework.getReferenceContent(FileName, TitleList);
ArrayList WordResult = MainDocumentPart_Framework.getReferenceContent(FileName, WordList);
var FinalResult = from first in TitleResult.ToArray()
from second in WordList.ToArray()
from third in xRefResult.ToArray()
select new[] { first, second, third };
foreach (var Item in FinalResult)
{
System.Windows.MessageBox.Show(Item.ToString());
//I like to view show, all the combination of arrays
//first1, second1, third1
//first1, second1, third2
//first1, second1, third3 ...........
}
I'm not really sure what kind of output you're after, and I don't think you need to use LINQ for this.
string outputStr = "";
for(int x = 0;x<xRefList.Count;x++)
{
for(int y = 0;y<WordList.Count;y++)
{
for(int z = 0;z<TitleList.Count;z++)
{
outputStr += xRefList[x] + " " + WordList[y] + " " + TitleList[z] + "\n";
}
}
}
MessageBox.Show(outputStr);
Would something like this work?

Need to add each number 0-x to end of line?

I'm making an app and I'm almost done. I just need to know how I can streamread a txt list and foreach line, add numbers 0-x (x will be the number the user puts in the textbox) and add it to a list. So basically, it would be like this
You import a list with 'dog' on one line, 'cat' on another, and 'fish' on the third. You type '5' into the textbox. the app puts all this into a list:
dog1
dog2
dog3
dog4
dog5
cat1
cat2
cat3
cat4
cat5
fish1
fish2
fish3
fish4
fish5
thanks!
The code below should work for you. I assume you can acquire the count value on your own.
var animals = File.ReadAllLines("yourFile.txt"); //new[] {"dog", "cat", "fish"};
var count = 5;
var merged =
from a in animals
from n in Enumerable.Range(1, count)
select a + n;
foreach (var m in merged)
Console.WriteLine(m); //act on each however you want
You can read a text file with File.ReadAllLines. This gives you an array you can iterate over with foreach.
In this foreach loop you can perform another loop from 1 to the number the user entered. int.Parse comes in handy for converting the string the user entered into a number C# can do something with. For the actual iteration you can use a for loop.
You can then add each item to a list.
There is a good example for reading each line in a filestream here: http://msdn.microsoft.com/en-us/library/e4y2dch9.aspx
private List<string> GetThings(string fileName, int count)
{
string[] lines = File.ReadAllLines(fileName);
List<string> result = new List<string>();
foreach (string item in lines)
{
for (int i = 1; i <= count; i++)
result.Add(item + i.ToString());
}
return result;
}
string[] inputList = File.ReadAllLines("yourFile.txt");
List<String> listOfThings = new List<String>();
foreach (string i in inputList)
{
for (int k = 0; k < 5; k++)
{
listOfThings.Add(i + " " + k.ToString());
}
}
then after that, you can print out the list like this:
foreach (string outp in listOfThings)
{
Console.WriteLine(outp);
}
output:
some value 0
some value 1
some value 2
some value 3
some value 4
some other value 0
some other value 1
some other value 2
some other value 3
some other value 4

Categories