Extracting 'single item' from Multi Dimensional Array (c#) - c#

Say I have the code
var marray = new int[,]{{0,1},{2,3},{4,5}};
Is it possible to get a reference to the first item - i.e. something that looked like:
var _marray = marray[0];
//would look like: var _marray = new int[,]{{0,1}};
Instead, when referencing marray from a one dimensional context, it sees marray as having length of 6
(i.e. new int[]{0,1,2,3,4,5})

Use a jagged array
var marray = new[] { new[] { 0, 1 }, new[] { 2, 3 }, new[] { 4, 5 } };
Console.WriteLine(marray[0][1]);

Related

Summing up a list of integer arrays using threads for each array in C# Console application

I have a List of int arrays. The list can be from 1 to 4 arrays.
I want to know how do i go about summing each array with individual threads and
placing the summed values into a new int array.
If the order of the new array is not important here you have a example
List<int[]> arraysList = new List<int[]>();
arraysList.Add(new int[] { 2, 3, 5 });
arraysList.Add(new int[] { 2, 3, 5, 9, 123, 5 });
arraysList.Add(new int[] { 3 });
arraysList.Add(new int[] { 9,8 });
ConcurrentBag<int> SummedValueOfEveryArray = new ConcurrentBag<int>();
Parallel.ForEach(arraysList, array =>
{
SummedValueOfEveryArray.Add(array.Sum());
});
//Your result
var result = SummedValueOfEveryArray.ToArray<int>();
//The sum of all arrays
var totalSum = SummedValueOfEveryArray.Sum();
This code will do what you ask. One side note however, this only parallelizes when .Net feels it could improve performance.
List<int[]> intlist = new List<int[]>();
int[] result = intlist.AsParallel().Select(arr => arr.Sum()).ToArray();
Given 1 to 4 arrays it may be that .Net never sees the point of parallelizing. But if you absolutely must you can force parallelization by using Parallel.For as shown below.
List<int[]> intlist = new List<int[]>();
int[] result = new int[intlist.Count];
Parallel.For(0, intlist.Count, i =>
{
result[i] = intlist[i].Sum();
});

How to access and re-format Jagged Array in C#

I have 2D array in c#, like this:
int[][] 2darray = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
how can I get one column as normal array, like
int[] array = 2darray[1][]; //example, not working
and have
int[] array = {3,4};
?
Thanks.
There are several reasons why your code can't compile
This way it works:
int[][] array2d = { new[]{ 1, 2 }, new[]{ 3, 4 }, new[]{ 5, 6 }, new[]{ 7, 8 } };
int[] array = array2d[0];
Problems:
2darray is not a valid variable name
The indexing is wrong
The initialization of the original array is wrong
EDIT:
As stated by #heltonbiker, if you require all elements of the first column, you can use this:
int[] col = array2d.Select(row => row[0]).ToArray();
For an array with two columns and four rows, you can use LINQ this way:
using System.Linq;
first_column = _2darray.Select(row => row[0]).ToArray();
Note that changing the first or second array will not change the other one.
You are confusing jagged arrays and multidimensional arrays in C#. While they are similar, there is a slight difference. Rows in a jagged array can have a different number of elements, while in a 2D-array they are of the same length. Therefore when working with jagged arrays you need to remember to write handling for a missing column element. I composed a sample console app below to show how both of them work - it uses 0 as a substitute for a missing element, but you can throw an error etc.:
using System.Collections.Generic;
namespace JaggedArrayExample
{
class Program
{
static void Main(string[] args)
{
//jagged array declaration
int[][] array1;
//jagged array declaration and assignment
var array2 = new int[][] {
new int[] { 1, 2 },
new int[] { 3, 4 },
new int[] { 5, 6 },
new int[] { 7, 8 }
};
//2D-array declaration
int[,] array3;
//2D-array declaration and assignment (implicit bounds)
var array4 = new int[,] {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
//2D-array declaration and assignment (explicit bounds)
var array5 = new int[4, 2] {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
//get rows and columns at index
var r = GetRow(array2, 1); //second row {3,4}
var c = GetColumn(array2, 1); //second column {2,4,6,8}
}
private static int[] GetRow(int[][] array, int index)
{
return array[index]; //retrieving the row is simple
}
private static int[] GetColumn(int[][] array, int index)
{
//but things get more interesting with columns
//especially if jagged arrays are involved
var retValue = new List<int>();
foreach (int[] r in array)
{
int ub = r.GetUpperBound(0);
if (ub >= index) //index within bounds
{
retValue.Add(r[index]);
}
else //index outside of bounds
{
retValue.Add(0); //default value?
//or you can throw an error
}
}
return retValue.ToArray();
}
}
}
try this, it should work
int[] array = array2d[1];
Change the name of the variable to array2d, you cannot have variable that starts with number, a variable can start with letter or underscore.

Merging arrays with common element

I want to merge arrays with common element. I have list of arrays like this:
List<int[]> arrList = new List<int[]>
{
new int[] { 1, 2 },
new int[] { 3, 4, 5 },
new int[] { 2, 7 },
new int[] { 8, 9 },
new int[] { 10, 11, 12 },
new int[] { 3, 9, 13 }
};
and I would like to merge these arrays like this:
List<int[]> arrList2 = new List<int[]>
{
new int[] { 1, 2, 7 },
new int[] { 10, 11, 12 },
new int[] { 3, 4, 5, 8, 9, 13 } //order of elements doesn't matter
};
How to do it?
Let each number be a vertex in the labelled graph. For each array connect vertices pointed by the numbers in the given array. E.g. given array (1, 5, 3) create two edges (1, 5) and (5, 3). Then find all the connected components in the graph (see: http://en.wikipedia.org/wiki/Connected_component_(graph_theory))
I'm pretty sure it is not the best and the fastest solution, but works.
static List<List<int>> Merge(List<List<int>> source)
{
var merged = 0;
do
{
merged = 0;
var results = new List<List<int>>();
foreach (var l in source)
{
var i = results.FirstOrDefault(x => x.Intersect(l).Any());
if (i != null)
{
i.AddRange(l);
merged++;
}
else
{
results.Add(l.ToList());
}
}
source = results.Select(x => x.Distinct().ToList()).ToList();
}
while (merged > 0);
return source;
}
I've used List<List<int>> instead of List<int[]> to get AddRange method available.
Usage:
var results = Merge(arrList.Select(x => x.ToList()).ToList());
// to get List<int[]> instead of List<List<int>>
var array = results.Select(x => x.ToArray()).ToList();
Use Disjoint-Set Forest data structure. The data structure supports three operations:
MakeSet(item) - creates a new set with a single item
Find(item) - Given an item, look up a set.
Union(item1, item2) - Given two items, connects together the sets to which they belong.
You can go through each array, and call Union on its first element and each element that you find after it. Once you are done with all arrays in the list, you will be able to retrieve the individual sets by going through all the numbers again, and calling Find(item) on them. Numbers the Find on which produce the same set should be put into the same array.
This approach finishes the merge in O(α(n)) amortized (α grows very slowly, so for all practical purposes it can be considered a small constant).

Initializing multidimensional arrays in c# (with other arrays)

In C#, it's possible to initialize a multidimensional array using constants like so:
Object[,] twodArray = new Object[,] { {"00", "01", "02"},
{"10", "11", "12"},
{"20", "21", "22"} };
I personally think initializing an array with hard coded constants is kind of useless for anything other than test exercises. Anyways, what I desperately need to do is initialize a new multidimensional array as above using existing arrays. (Which have the same item count, but contents are of course only defined at runtime).
A sample of what I would like to do is.
Object[] first = new Object[] {"00", "01", "02"};
Object[] second = new Object[] {"10", "11", "12"};
Object[] third = new Object[] {"20", "21", "22"};
Object[,] twodArray = new Object[,] { first, second, third };
Unfortunately, this doesn't compile as valid code. Funny enough, when I tried
Object[,] twodArray = new Object[,] { {first}, {second}, {third} };
The code did compile and run, however the result was not as desired - a 3 by 3 array of Objects, what came out was a 3 by 1 array of arrays, each of which had 3 elements. When that happens, I can't access my array using:
Object val = twodArray[3,3];
I have to go:
Object val = twodArray[3,1][3];
Which obviously isn't the desired result.
So, is there any way to initialize this new 2D array from multiple existing arrays without resorting to iteration?
This would work if you switched to jagged arrays:
int[] arr1 = new[] { 1, 2, 3 };
int[] arr2 = new[] { 4, 5, 6 };
int[] arr3 = new[] { 7, 8, 9 };
int[][] jagged = new[] { arr1, arr2, arr3 };
int six = jagged[1][2];
Edit To clarify for people finding this thread in the future
The code sample above is also inadequate as it results in an array of arrays (object[object[]]) rather than a jagged array (object[][]) which are conceptually the same thing but distinct types.
You are trying to assign array references to an array. For more details please read - Jagged Arrays.
Try this,
Object[] first = new Object[] { "00", "01", "02" };
Object[] second = new Object[] { "10", "11", "12" };
Object[] third = new Object[] { "20", "21", "22" };
Object[][] result = { first, second, third };
foreach (object [] ar in result)
{
foreach (object ele in ar)
{
Console.Write(" " + ele);
}
Console.WriteLine();
}
I'm struggling to fully understand what you're really trying to achieve. If I got it right, you have some "lists" of strings, which you need to store in another list.
First of all, I'd recommend you to use a more modern approach than arrays. C# offers you IEnumerable<> and IList<> interfaces and all the stuff that derives from them, so no need to stick with old fashioned arrays.
You could do something like this:
var list1 = new List<string> { "foo1", "foo2", "foo3" };
var list2 = new List<string> { "foo4", "foo5", "foo6" };
var list3 = new List<string> { "foo7", "foo8", "foo9" };
var listOfStrings = new List<List<string>> { list1, list2, list3 };
Then if you want to access "foo6" you write:
var temp = listOfStrings[1][2];
The following works just fine:
var a = new object[] { 0, 1, 1, 2 };
var b = new object[] { "0", "5", "0", "0" };
var c = new object[] { true, true, true, false };
object[][] m = new object[][] { a, b, c };
var two = m[0][3];
var bar = m[1][1];
var f = m[2][3];

How can I repopulate an array?

I have code that populates an array:
var counters = new[] { 1,2,4,8 }
This works good but later on in my code I would like to do something like this:
counters = new[] { 2,2,3,5 }
Is there some way I can do this? I am very new to C# and still learning
The code you wrote in your question would work fine: the first line will create a new array, the second line will also create a new array and will assign the new array to the existing variable. The old integer array will be replaced (and later be garbage collected)
What is your problem? Your code is valid:
var counters = new[] { 1,2,4,8 };
counters = new[] { 2, 2, 3, 5 };
Your code will work, but it does not repopulate the array, it creates a new array.
You could do this
Array.Copy( new int[] { 2,2,3,5 }, counters, 4);
Yes, you can do as you have written.
However, note that this will create a new array, not replace the values in the old array. That makes a difference if another variable holds a reference to the same array.
Example 1
var counters = new[] { 1, 2, 4, 8 };
var counters2 = counters;
counters = new[] { 2, 2, 3, 5 };
Console.WriteLine(counters2[0].ToString()); // outputs 1
Example 2
var counters = new[] { 1, 2, 4, 8 };
var counters2 = counters;
counters[0] = 2;
counters[1] = 2;
counters[2] = 3;
counters[3] = 5; // or use Array.Copy as suggested by Henrik
Console.WriteLine(counters2[0].ToString()); // outputs 2

Categories