Related
I have a problem retrieving values in the order that I want
I wrote a simple code to demonstrate :
List<string> st1 = new List<string>() {"st11","st12"};
List<string> st2 = new List<string>() {"st21","st22"};
ArrayList stringArrayList = new ArrayList();
stringArrayList.Add(st1);
stringArrayList.Add(st2);
string[] n1 = new string[10];
int i = 0;
foreach (List<string> item in stringArrayList)
{
foreach (var item2 in item)
{
n1[i] = item2;
i++;
}
}
in this code the output will be : st11,st12 st21,s22
i want it to get values like this : st11,st21 st12,st22
i want the information stored in this order "st11,st21 st12,st22" into n1
If the lenght of the list are the same you can make something like this:
int j = 0;
int lengthToLoop = st1.length;
for(int i = 0; i < lengthToLoop; i++)
{
n1[j++] = st1[i];
n1[j++] = st2[i];
}
If the length are not equal you can calculate the minimum, copy the minimum length of element from each and then copy the remaining.
Here's an implementation that will do what you're looking for, and will also handle jagged arrays.
List<string> st1 = new List<string>() { "st11", "st12" };
List<string> st2 = new List<string>() { "st21", "st22", };
ArrayList stringArrayList = new ArrayList();
stringArrayList.Add(st1);
stringArrayList.Add(st2);
//this will protect us against differing max indexes if the 2D array is jagged.
int maxIndex = 0;
int totalElements = 0;
foreach (List<string> currentList in stringArrayList)
{
if (currentList.Count > maxIndex)
{
maxIndex = currentList.Count;
}
totalElements += currentList.Count;
}
string[] n1 = new string[totalElements];
int i = 0;
for (int j = 0; j < maxIndex; j++)
{
for (int k = 0; k < stringArrayList.Count; k++)
{
List<string> currentStringArray = (List<string>)stringArrayList[k];
if (j < currentStringArray.Count)
{
n1[i] = currentStringArray[j];
i++;
}
}
}
You have to reverse the two loops, making the outer loop the inner loop.
Use a for loop instead of a foreach loop for the outer loop using the length of the string arrays as the delimiter.
Also: Don't use ArrayList, but a real typed list.
List<string> st1 = new List<string>() { "st11", "st12" };
List<string> st2 = new List<string>() { "st21", "st22" };
List<List<string>> stringArrayList = new List<List<string>>();
stringArrayList.Add(st1);
stringArrayList.Add(st2);
// Get length of first string array
int firstArrayLength = stringArrayList[0].Count;
string[] n1 = new string[10];
int i = 0;
// For each position in the arrays from 0 to firstArrayLength -1 do
for (int arrayPosition = 0; arrayPosition < firstArrayLength; arrayPosition++)
{
// For each of the string array
foreach (var stringArray in stringArrayList)
{
// Get the item from the stringArray at position arrayPosition
n1[i] = stringArray[arrayPosition];
i++;
}
}
First, check the max list length, and then take item at index (0,1,3... till max) from every list. Don't forget to check if the index exist. In addition, you can set the exact size of n1 because it is the sum of all list count. You don't need to have a separated line for i++ in this case.
List<string> st1 = new List<string> { "st11", "st12" };
List<string> st2 = new List<string> { "st21", "st22" };
List<List<string>> stringArrayList = new List<List<string>> {st1, st2};
int maxCount = stringArrayList.Max(x => x.Count);
int totalItems = 0;
stringArrayList.ForEach(x=> totalItems+= x.Count);
string[] n1 = new string[totalItems];
int i = 0;
for (int index = 0; index < maxCount; index++)
{
foreach (var list in stringArrayList)
{
if (list.Count > index)
{
n1[i++] = list[index];
}
}
}
Looking for some help in figuring this out. I have two arrays of names. What I need to do is bubble sort them (which I have done, see code below), and populate the third array with the values from the first two array, leaving out duplicates, and not sorting the third array. Below is my example code, which completely works for what I am doing, except I need to use a loop to fill in the third array (logical exercise).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MergeArray
{
class Program
{
static void Main(string[] args)
{
string[] names1 = { "Bob", "John", "Bill", "Sandy", "Betty", "Bart", "Patty" };
string[] names2 = { "Andy", "Chris", "Bill", "Walter" };
string[] names3 = new string[names1.Length + names2.Length];
string temp;
foreach (string i in names1)
{
for (int j = 0; j < names1.Length - 1; j++)
{
if (String.Compare(names1[j], names1[j+1]) > 0)
{
temp = names1[j];
names1[j] = names1[j + 1];
names1[j + 1] = temp;
}
}
}
foreach (string i in names2)
{
for (int j = 0; j < names2.Length - 1; j++)
{
if (String.Compare(names2[j], names2[j + 1]) > 0)
{
temp = names2[j];
names2[j] = names2[j + 1];
names2[j + 1] = temp;
}
}
}
names1.CopyTo(names3, 0);
names2.CopyTo(names3, names1.Length);
Console.WriteLine(String.Join(Environment.NewLine, names3.Distinct().ToArray()));
Console.ReadLine();
}
}
}
In the end, this code does what I need it to do, which is populate the third array with "Bart, Betty, Bill, Bob, John, Patty, Sandy, Andy, Chris, Walter". It doesn't fill in the duplicate "Bill" and it just adds the two arrays together, without sorting the third (which is what I need to do). What I need help with is turning the part where I fill in the third array into a loop instead of the:
names1.CopyTo(names3, 0);
names2.CopyTo(names3, names1.Length);
Console.WriteLine(String.Join(Environment.NewLine, names3.Distinct().ToArray()));
Please help me out to understand what I need to do here.
Assuming that your bubble sort successfully sorts you elements, you can use a modified merge operation to put together the final array. Basically a merge takes two sorted arrays and puts them together by comparing the "top" elements of each array and moving that one to the composite array.
You would just have to check for duplicate while you are doing this. And since your arrays are both sorted, all duplicates will clump together into groups, so you would only need to keep track of the most recent duplicate.
Something like this (which is very verbose and heavily commented) could work:
public static string[] MergeNoDuplicates(string[] left, string[] right)
{
var mergedArray = new string[left.Length + right.Length];
//since the arrays are sorted, we only need to keep track of the most recent duplicate
string duplicateChecker = null;
int mergeIndex = 0;
int l = 0; //index for left array
int r = 0; //index for right array
//while there are more element in at least one of the two arrays
bool leftHasElements = l < left.Length;
bool rightHasElements = r < right.Length;
while (leftHasElements && rightHasElements)
{
string leftString = left[l];
string rightString = right[r];
int comparisonResult = leftString.CompareTo(rightString);
if (comparisonResult < 0) //left string comes before right string
{
//not a duplicate
if (leftString.CompareTo(duplicateChecker) != 0)
{
mergedArray[mergeIndex] = leftString;
mergeIndex++;
duplicateChecker = leftString;
}
//regardless of whether it's a duplicate move onto the next element
l++;
}
else if (comparisonResult > 0) //right string comes before left
{
if (rightString.CompareTo(duplicateChecker) != 0)
{
mergedArray[mergeIndex] = rightString;
mergeIndex++;
duplicateChecker = rightString;
}
r++;
}
else //comparisonResult by default == 0
{
//since they are the same string, just insert one (if needed), but increment both arrays
if (leftString.CompareTo(duplicateChecker) != 0)
{
mergedArray[mergeIndex] = leftString;
mergeIndex++;
duplicateChecker = leftString;
}
l++;
r++;
}
leftHasElements = l < left.Length;
rightHasElements = r < right.Length;
}
//now at least one of the arrays is empty, so add all of the remaining
//non-duplicate elements of the other to the array
//if either is false, the loop won't execute in the first place
while (leftHasElements)
{
string leftString = left[l];
if (leftString.CompareTo(duplicateChecker) != 0)
{
mergedArray[mergeIndex] = leftString;
mergeIndex++;
duplicateChecker = leftString;
}
l++;
leftHasElements = l < left.Length;
}
while (rightHasElements)
{
string rightString = right[r];
if (rightString.CompareTo(duplicateChecker) != 0)
{
mergedArray[mergeIndex] = rightString;
mergeIndex++;
duplicateChecker = rightString;
}
r++;
rightHasElements = r < right.Length;
}
//now remove null elements (if needed) and return
//alternatively, just use LINQ's TakeWhile and ToArray
if (mergeIndex == mergedArray.Length)
return mergedArray;
var returnedArray = new string[mergeIndex];
Array.Copy(mergedArray, returnedArray, mergeIndex);
return returnedArray;
}
Demo
Ohh the power of linq!
string[] names1 = { "Bob", "John", "Bill", "Sandy", "Betty", "Bart", "Patty" };
string[] names2 = { "Andy", "Chris", "Bill", "Walter" };
string[] names3 = names1.Union(names2).Distinct().ToArray();
As ryanyuyu suggested, use a modified merge operation.
This will come after you have already sorted them.
int m = 0;
int n = 0;
while ((m < names1.Count) && (n < names1.Count))
{
int comparison = String.Compare(names1[m], names2[n]);
if (comparison < 0) // names1[m] is before names2[n]
{
names3.Add(names1[m]);
m = m + 1;
}
else if (comparison > 1) //names2[n] is before names1[m]
{
names3.Add(names2[n]);
n = n + 1;
}
else //names1[m] is equal to names2[n], only add one.
{
names3.Add(names1[m]);
m = m + 1;
n = n + 1;
}
}
//either names1 or names2 ran out of entries. fill names3 with whatever is left
while (m < names1.Count)
{
names3.Add(names1[m]);
m = m + 1;
}
while (n < names2.Count)
{
names3.Add(names2[n]);
n = n + 1;
}
If it is possible the original arrays might themselves contain duplicates, you can track which values have been added using a HashSet.
List<string> names1 = new List<string>();
List<string> names2 = new List<string>();
List<string> names3 = new List<string>();
var included = new HashSet<string>();
int m = 0;
int n = 0;
while ((m < names1.Count) && (n < names1.Count))
{
int comparison = String.Compare(names1[m], names2[n]);
if (comparison < 0)
{
if(included.Add(names1[m]))
{
names3.Add(names1[m]);
}
m = m + 1;
}
else if (comparison > 1)
{
if (included.Add(names2[n]))
{
names3.Add(names2[n]);
}
n = n + 1;
}
else
{
names3.Add(names1[m]);
m = m + 1;
n = n + 1;
}
}
while (m < names1.Count)
{
if (included.Add(names1[m]))
{
names3.Add(names1[m]);
}
m = m + 1;
}
while (n < names2.Count)
{
if (included.Add(names2[n]))
{
names3.Add(names2[n]);
}
n = n + 1;
}
Of course at this point you might as well make names3 a HashSet and skip the extra checks. The only benefit we have for keeping included separate is that names3 retains the sorted order. There is no guarantee this will be true if names3 itself were the HashSet and you did names3.ToArray() at the end.
Why not:
List<string> names = new List<string>();
names.AddRange(names1);
names.AddRange(names2);
names.Sort();
string[] names3 = names.Distinct().ToArray();
You could just use .Union:
string[] names1 = { "Bob", "John", "Bill", "Sandy", "Betty", "Bart", "Patty" };
string[] names2 = { "Andy", "Chris", "Bill", "Walter" };
string[] names3 = names1.Union(names2).ToArray();
I'd suggest copying to a List<>, using "Distinct":
Use "AddRange()" to add the second array.
Use "Distinct()" to eliminate the duplicates,
Finally, convert the list back to an array.
EXAMPLE:
List<string> myList = myArray.Cast<string>().ToList();
myList.AddRange(mySecondArray);
string[] myNewArray = myList.Distinct().toArray();
I would use a loop like this:
int names1I = 0;
int names2I = 0;
for(int i = 0; names1I < names1.Length && names2I < names2.Length; i++)
{
while(names1I < names1.Length && names3.Contains(names1[names1I]))
names1I++;
while(names2I < names2.Length && names3.Contains(names2[names2I]))
names2I++;
if(names1I == names1.Length) //if you have already reached the end of array 1, you have to use array 2
names3[i] = names2[names2I++];
else if(names2I == names2.Length) //if you have already reached the end of array 2, you have to use array 1
names3[i] = names1[names1I++];
else //else take the smaller of the 2 possible values
names3[i] = (names1[names1I] <= names2[names2I]) ? names1[names1I++] : names2[names2I++];
}
If I got an array like:
string[] test = new string[5] { "hello", "world", "test", "world", "world"};
How can I make a new array out of the ones that is the same string, "world" that is where you on before hand know how many there are, here 3?
I was thinking of something like:
string[] newArray = new string[3];
for (int i = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newArray[i] = test[i];
}
}
The problem is here: newArray[i] = test[i];
Since it's iterating from 0 to 4, there's gonna be an error since newArray is limited to 3.
How do solve this?
EDIT: I need it to be that from test (the old array) position 1, 3 and 4 should be stored at 0, 1 and 2 in the newArray.
You want to use Linq:
var newArray = test.Where(x => x.Contains("world")).ToArray();
Use a List<string> instead:
List<string> newList = new List<string>();
for (int i = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newList.Add(test[i]);
}
}
If you really need it as an array later.. convert the list:
string[] newArray = newList.ToArray();
You are using the same index i for both test and newArray. I would suggest you create another counter variable and increment it:
string[] newArray = new string[3];
int counter = 0;
for (int i = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newArray[counter] = test[i];
counter++;
}
}
This isn't technically your question but if you wish to make a load of arrays based of those with the same word you could do
test.GroupBy(x => x).ToList();
this will give you a List of Lists.. with your test data this will be
list1 - hello
list2 - world world world
list3 - test
Example use
var lists = test.GroupBy(x => x).ToList();
foreach(var list in lists)
{
foreach(var str in list)
{
Console.WriteLine(str);
}
Console.WriteLine();
}
With an extra helper index variable
string[] newArray = new string[3];
for (int i = 0, j = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newArray[j++] = test[i];
if (j >= newArray.Length)
break;
}
}
I have tried several time but couldn’t find the way to solve my problem. Here my txt file shown in below.
695
748
555
695
748
852
639
748
I put the for loop to read the data and put them in to array. So now I want to filter repeat numbers from the input txt data. How can I have a count of repeated data.
static void Main(string[] args)
{
int x = 0;
int count = 0;
String[] line = File.ReadAllLines("C:/num.txt");
int n = line.Length;
String[] res = new String[n];
for (int i = 0; i < n; i++)
{
res[i] = line[i].Substring(x,x+8);
Console.WriteLine(res[i]);
}
Console.ReadLine();
}
You use GroupBy()
var result = res.GroupBy(x => x);
foreach(var g in result)
{
Console.WriteLine(g.Key + " count: " + g.Count());
}
Somehow you have to keep track of things you have seen before.
One way to do that is to place the numbers in a list the first time you see them. If a given number is already in the list, filter it out on the latter occurrences.
Here's an example with the list. Note that your code to fetch a substring of the input crashes.
static void Main(string[] args)
{
int x = 0;
int count = 0;
String[] line = new string[] { "123", "456", "123" }; //File.ReadAllLines("C:/num.txt");
int n = line.Length;
String[] res = new String[n];
List<string> observedValues = new List<string>();
for (int i = 0; i < n; i++)
{
string consider = line[i]; // This code crashes: .Substring(x, x + 8);
if (!observedValues.Contains(consider))
{
observedValues.Add(consider);
res[i] = consider;
Console.WriteLine(res[i]);
}
else
{
Console.WriteLine("Skipped value: " + consider + " on line " + i);
}
Console.ReadLine();
}
}
Another method is to pre-sort the input so that duplicates are adjacent.
Example:
(Note, you may want to remove white space in the input prior to sorting. Leading white space will break this code).
static void Main(string[] args)
{
int x = 0;
int count = 0;
String[] line = new string[] { "123", "456", "123" }; //File.ReadAllLines("C:/num.txt");
int n = line.Length;
String[] res = new String[n];
string previous = null;
Array.Sort(line); // Ensures that equal values are adjacent
for (int i = 0; i < n; i++)
{
string consider = line[i].Trim(); // Note leading whitespace will break this.
if (consider != previous)
{
previous = consider;
res[i] = consider;
Console.WriteLine(res[i]);
}
else
{
Console.WriteLine("Skipped value: " + consider + " on line " + i);
}
Console.ReadLine();
}
}
So now I want to filter repeat numbers from the input txt data.
if all you need is filter out duplicates you can use this:
String[] line = File.ReadAllLines("C:/num.txt");
var filteredLines = line.Distinct();
foreach (var item in filteredLines)
Console.WriteLine(item);
I've got a two-dimensional array,
string[,] table = {
{ "aa", "aaa" },
{ "bb", "bbb" }
};
And I'd like to foreach through it like this,
foreach (string[] row in table)
{
Console.WriteLine(row[0] + " " + row[1]);
}
But, I get the error:
Can't convert type string to string[]
Is there a way I can achieve what I want, i.e. iterate through the first dimension of the array with the iterator variable returning me the one-dimensional array for that row?
Multidimensional arrays aren't enumerable. Just iterate the good old-fashioned way:
for (int i = 0; i < table.GetLength(0); i++)
{
Console.WriteLine(table[i, 0] + " " + table[i, 1]);
}
As others have suggested, you could use nested for-loops or redeclare your multidimensional array as a jagged one.
However, I think it's worth pointing out that multidimensional arrays are enumerable, just not in the way that you want. For example:
string[,] table = {
{ "aa", "aaa" },
{ "bb", "bbb" }
};
foreach (string s in table)
{
Console.WriteLine(s);
}
/* Output is:
aa
aaa
bb
bbb
*/
If you define your array like this:
string[][] table = new string[][] {
new string[] { "aa", "aaa" },
new string[]{ "bb", "bbb" }
};
Then you can use a foreach loop on it.
UPDATE: I had some time on my hands, so ... I went ahead and fleshed out this idea. See below for the code.
Here's a bit of a crazy answer:
You could do what you're looking for -- essentially treat a two-dimensional array as a table with rows -- by writing a static method (perhaps an extension method) that takes a T[,] and returns an IEnumerable<T[]>. This would require copying each "row" of the underlying table into a new array, though.
A perhaps better (though more involved) approach would be to actually write a class that implements IList<T> as a wrapper around a single "row" of a two-dimensional array (you would probably set IsReadOnly to true and just implement the getter for the this[int] property and probably Count and GetEnumerator; everything else could throw a NotSupportedException). Then your static/extension method could return an IEnumerable<IList<T>> and provide deferred execution.
That way you could write code pretty much like what you have:
foreach (IList<string> row in table.GetRows()) // or something
{
Console.WriteLine(row[0] + " " + row[1]);
}
Just a thought.
Implementation suggestion:
public static class ArrayTableHelper {
public static IEnumerable<IList<T>> GetRows<T>(this T[,] table) {
for (int i = 0; i < table.GetLength(0); ++i)
yield return new ArrayTableRow<T>(table, i);
}
private class ArrayTableRow<T> : IList<T> {
private readonly T[,] _table;
private readonly int _count;
private readonly int _rowIndex;
public ArrayTableRow(T[,] table, int rowIndex) {
if (table == null)
throw new ArgumentNullException("table");
if (rowIndex < 0 || rowIndex >= table.GetLength(0))
throw new ArgumentOutOfRangeException("rowIndex");
_table = table;
_count = _table.GetLength(1);
_rowIndex = rowIndex;
}
// I didn't implement the setter below,
// but you easily COULD (and then set IsReadOnly to false?)
public T this[int index] {
get { return _table[_rowIndex, index]; }
set { throw new NotImplementedException(); }
}
public int Count {
get { return _count; }
}
bool ICollection<T>.IsReadOnly {
get { return true; }
}
public IEnumerator<T> GetEnumerator() {
for (int i = 0; i < _count; ++i)
yield return this[i];
}
// omitted remaining IList<T> members for brevity;
// you actually could implement IndexOf, Contains, etc.
// quite easily, though
}
}
...now I think I should give StackOverflow a break for the rest of the day ;)
It depends on how you define your multi-dimensional array. Here are two options:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
// First
string[,] arr1 = {
{ "aa", "aaa" },
{ "bb", "bbb" }
};
// Second
string[][] arr2 = new[] {
new[] { "aa", "aaa" },
new[] { "bb", "bbb" }
};
// Iterate through first
for (int x = 0; x <= arr1.GetUpperBound(0); x++)
for (int y = 0; y <= arr1.GetUpperBound(1); y++)
Console.Write(arr1[x, y] + "; ");
Console.WriteLine(Environment.NewLine);
// Iterate through second second
foreach (string[] entry in arr2)
foreach (string element in entry)
Console.Write(element + "; ");
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Press any key to finish");
Console.ReadKey();
}
}
}
Here's a simple extension method that returns each row as an IEnumerable<T>. This has the advantage of not using any extra memory:
public static class Array2dExt
{
public static IEnumerable<IEnumerable<T>> Rows<T>(this T[,] array)
{
for (int r = array.GetLowerBound(0); r <= array.GetUpperBound(0); ++r)
yield return row(array, r);
}
static IEnumerable<T> row<T>(T[,] array, int r)
{
for (int c = array.GetLowerBound(1); c <= array.GetUpperBound(1); ++c)
yield return array[r, c];
}
}
Sample usage:
static void Main()
{
string[,] siblings = { { "Mike", "Amy" }, { "Mary", "Albert" }, {"Fred", "Harry"} };
foreach (var row in siblings.Rows())
Console.WriteLine("{" + string.Join(", ", row) + "}");
}
string[][] table = { ... };
string[][] languages = new string[2][];
languages[0] = new string[2];
languages[1] = new string[3];
// inserting data into double dimensional arrays.
for (int i = 0; i < 2; i++)
{
languages[0][i] = "Jagged"+i.ToString();
}
for (int j = 0; j < 3; j++)
{
languages[1][j] = "Jag"+j.ToString();
}
// doing foreach through 2 dimensional arrays.
foreach (string[] s in languages)
{
foreach (string a in s)
{
Console.WriteLine(a);
}
}
Using LINQ you can do it like this:
var table_enum = table
// Convert to IEnumerable<string>
.OfType<string>()
// Create anonymous type where Index1 and Index2
// reflect the indices of the 2-dim. array
.Select((_string, _index) => new {
Index1 = (_index / 2),
Index2 = (_index % 2), // ← I added this only for completeness
Value = _string
})
// Group by Index1, which generates IEnmurable<string> for all Index1 values
.GroupBy(v => v.Index1)
// Convert all Groups of anonymous type to String-Arrays
.Select(group => group.Select(v => v.Value).ToArray());
// Now you can use the foreach-Loop as you planned
foreach(string[] str_arr in table_enum) {
// …
}
This way it is also possible to use the foreach for looping through the columns instead of the rows by using Index2 in the GroupBy instead of Index 1. If you don't know the dimension of your array then you have to use the GetLength() method to determine the dimension and use that value in the quotient.
I'm not a big fan of this method because of the memory usage involved, but if you use the arrays it produces, it isn't such a waste.
public static void ForEachRow<T>(this T[,] list, Action<int, T[]> action)
{
var len = list.GetLength(0);
var sub = list.GetLength(1);
T[] e;
int i, j;
for (i = 0; i < len; i++)
{
e = new T[sub];
for (j = 0; j < sub; j++)
{
e[j] = list[i, j];
}
action(i, e);
}
}
Implementation:
var list = new[,]{0x0, 0x1, 0x2, 0x4, 0x8};
list.ForEachRow((i, row) =>
{
for (var j = 0; j < row.Length; j++)
{
Console.WriteLine("[{0},{1}]: {2}", i, j, row[j]);
}
});
The other solution I found is less memory intensive, but will use more CPU, especially when the dimensions of the arrays' entries are larger.
public static void ForEachRow<T>(this T[,] list, Action<int, IEnumerable<T>> action)
{
var len = list.GetLength(0);
var sub = list.GetLength(1);
int i, j;
IEnumerable<T> e;
for (i = 0; i < len; i++)
{
e = Enumerable.Empty<T>();
for (j = 0; j < sub; j++)
{
e = e.Concat(AsEnumerable(list[i, j]));
}
action(i, e);
}
}
private static IEnumerable<T> AsEnumerable<T>(T add)
{
yield return add;
}
Implementation:
var list = new[,]{0x0, 0x1, 0x2, 0x4, 0x8};
list.ForEachRow((i, row) =>
{
var j = 0;
forrach (var o in row)
{
Console.WriteLine("[{0},{1}]: {2}", i, j, o);
++j;
}
});
As a whole, I find the first option to be more intuitive, especially if you want to access the produced array by its indexer.
At the end of the day, this is all just eye candy, neither methods should really be used in favour of directly accessing the source array;
for (var i = 0; i < list.GetLength(0); i++)
{
foreach (var j = 0; j < list.GetLength(1); j++)
{
Console.WriteLine("[{0},{1}]: {2}", i, j, list[i, j]);
}
}
Remember that a multi-dimensional array is like a table. You don't have an x element and a y element for each entry; you have a string at (for instance) table[1,2].
So, each entry is still only one string (in your example), it's just an entry at a specific x/y value. So, to get both entries at table[1, x], you'd do a nested for loop. Something like the following (not tested, but should be close)
for (int x = 0; x < table.Length; x++)
{
for (int y = 0; y < table.Length; y += 2)
{
Console.WriteLine("{0} {1}", table[x, y], table[x, y + 1]);
}
}
I try this. I hope to help. It work with
static void Main()
{
string[,] matrix = {
{ "aa", "aaa" },
{ "bb", "bbb" }
};
int index = 0;
foreach (string element in matrix)
{
if (index < matrix.GetLength(1))
{
Console.Write(element);
if (index < (matrix.GetLength(1) - 1))
{
Console.Write(" ");
}
index++;
}
if (index == matrix.GetLength(1))
{
Console.Write("\n");
index = 0;
}
}