I'm trying to create an array of arrays that will be using repeated data, something like below:
int[] list1 = new int[4] { 1, 2, 3, 4 };
int[] list2 = new int[4] { 5, 6, 7, 8 };
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[,] lists = new int[4, 4] { list1 , list2 , list3 , list4 };
I can't get it to work and so I'm wondering if I'm approaching this wrong.
What I'm attempting to do is create some sort of method to create a long list of the values so I can process them in a specific order, repeatedly. Something like,
int[,] lists = new int[90,4] { list1, list1, list3, list1, list2, (and so on)};
for (int i = 0; i < 90; ++i) {
doStuff(lists[i]);
}
and have the arrays passed to doStuff() in order. Am I going about this entirely wrong, or am I missing something for creating the array of arrays?
What you need to do is this:
int[] list1 = new int[4] { 1, 2, 3, 4};
int[] list2 = new int[4] { 5, 6, 7, 8};
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[][] lists = new int[][] { list1 , list2 , list3 , list4 };
Another alternative would be to create a List<int[]> type:
List<int[]> data=new List<int[]>(){list1,list2,list3,list4};
The problem is that you are attempting to define the elements in lists to multiple lists (not multiple ints as is defined). You should be defining lists like this.
int[,] list = new int[4,4] {
{1,2,3,4},
{5,6,7,8},
{1,3,2,1},
{5,4,3,2}};
You could also do
int[] list1 = new int[4] { 1, 2, 3, 4};
int[] list2 = new int[4] { 5, 6, 7, 8};
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[,] lists = new int[4,4] {
{list1[0],list1[1],list1[2],list1[3]},
{list2[0],list2[1],list2[2],list2[3]},
etc...};
I think you may be looking for Jagged Arrays, which are different from multi-dimensional arrays (as you are using in your example) in C#. Converting the arrays in your declarations to jagged arrays should make it work. However, you'll still need to use two loops to iterate over all the items in the 2D jagged array.
This loops vertically but might work for you.
int rtn = 0;
foreach(int[] L in lists){
for(int i = 0; i<L.Length;i++){
rtn = L[i];
//Do something with rtn
}
}
The following will give you an array in the iterator variable of foreach
int[][] ar =
{
new []{ 50, 50, 1 },
new []{ 80, 40, 2 },
new []{ 10, 60, 3 },
new []{ 51, 38, 4 },
new []{ 48, 38, 5 }
};
Related
For example I have this as List<List<int>>:
[2,4,4,2,5]
[1,3,6,3,8]
[0,3,9,0,0]
Should return the sum but only taking cells assuming that the cell count is always the same:
[3, 10, 19, 5, 13]
I am trying to find an easy way to solve this using Linq if it is possible because I am doing this with a lot of for loops and if conditions and I am complicating myself.
Is there a possible way to achieve this using Linq?
Linq approach
List<List<int>> items = new List<List<int>>() {
new List<int> { 2, 4, 4, 2, 5 },
new List<int> { 1, 3, 6, 3, 8 },
new List<int> { 0, 3, 9, 0, 0 } };
List<int> result = Enumerable.Range(0, items.Min(x => x.Count)).Select(x => items.Sum(y => y[x])).ToList();
var xx = new List<List<int>>() {
new List<int>() { 2, 4, 4, 2, 5 },
new List<int>() { 1, 3, 6, 3, 8 },
new List<int>() { 0, 3, 9, 0, 0 },
};
var y = xx.Aggregate((r, x) => r.Zip(x).Select(p => p.First + p.Second).ToList());
I am doing this with a lot of for loops and if conditions and I am complicating myself.
You can accomplish it by using a single for loop.
Two possible approaches to achieve that are:
Approach 1
Creating an array with a capacity equal to the size of either of the lists in the original list collection
Filling the array with 0s
Looping through all lists in the original list collection, aggregating the sum for each index
Approach 2
Creating a list based on the first list in the original list collection
Looping through all subsequent lists in the original list collection, aggregating the sum for each index
Both approaches benefit from the assumption given in the question post:
[...] assuming that the cell count is always the same
If your original list collection is defined as a List<List<int>>:
List<List<int>> valuesCollection = new()
{
new() { 2, 4, 4, 2, 5 },
new() { 1, 3, 6, 3, 8 },
new() { 0, 3, 9, 0, 0 },
};
, the two approaches may be implemented as follows:
Approach 1
var indexCount = valuesCollection[0].Count;
var sums = new int[indexCount];
Array.Fill(sums, 0);
foreach (var values in valuesCollection)
{
for (var i = 0; i < sums.Length; i++)
{
sums[i] += values[i];
}
}
Approach 2
Note: Uses namespace System.Linq
var sums = valuesCollection[0].ToList();
foreach (var values in valuesCollection.Skip(1))
{
for (var i = 0; i < sums.Count; i++)
{
sums[i] += values[i];
}
}
Using either approach, sums's resulting content will be { 3, 10, 19, 5, 13 }.
Example fiddle here.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have multiple arrays of objects T -> where T : IComparable<T>.
Each array contains unique elements. An element could be present in multiple arrays but not multiple times in the same array. I need to move all elements that are contains in all arrays to the front of the arrays (in the same order) and get the count of the elements (that are moved so i can have a slice of each array). What would be the most optimal algorithm perf/memory wise?
var a = new[] {4, 5, 6, 7, 8};
var b = new[] {7, 4, 3, 1, 2};
... (up to 8 arrays)
int length = SortAsc(a, b, ...)
// a -> {4, 7, 5, 6, 8}
// b -> {4, 7, 3, 1, 2}
// length = 2
You can use the Intersect method (in System.Linq) to get all the common items. Then you can use Union to join the intersection with the original array. Because we specify intersection.Union(array) instead of array.Union(intersection), the intersection items will appear first in the result. Also, the set operation methods (Union, Intersect, Except) will automatically remove any duplicates:
var a = new[] {4, 5, 6, 7, 8};
var b = new[] {7, 4, 3, 1, 2};
// Common items, ordered by value ascending
var intersection = a.Intersect(b).OrderBy(i => i);
// Union the intersection to put the intersected items first
// (the duplicates are removed automatcially by Union)
a = intersection.Union(a).ToArray();
b = intersection.Union(b).ToArray();
To get the intersection of multiple arrays, it would be handy to add them to a list and then we can use the Aggregate method:
var a = new[] {4, 5, 6, 7, 8};
var b = new[] {7, 4, 3, 1, 2};
var c = new[] {9, 1, 7, 4, 2};
var d = new[] {3, 1, 4, 2, 7};
var e = new[] {3, 7, 4, 1, 2};
var f = new[] {7, 4, 3, 1, 9};
var g = new[] {4, 1, 7, 9, 8};
var h = new[] {3, 2, 6, 7, 4};
var arrays = new List<int[]> {a, b, c, d, e, f, g, h};
var intersection = arrays.Aggregate((accumulation, next) =>
accumulation.Intersect(next).ToArray()).OrderBy(i => i);
Note that this is not the best performing solution, just a simple one to write. :)
Oh, and you can get the count of common items using intersection.Count().
As per I understood, I made an example in a console app:
This is the program.cs
static void Main(string[] args)
{
var a = new int[5] { 4, 5, 6, 7, 8 };
var b = new int[5] { 7, 4, 3, 1, 2 };
var c = new int[5] { 4, 2, 1, 7, 9 };
var d = new int[5] { 1, 2, 6, 4, 5 };
var leng = SortAsc(a, b, c, d);
if (leng.Arrays.Count > 0)
{
Console.WriteLine($"Length: {leng.Arrays.Count}");
foreach (var item in leng.Arrays)
{
for (int i = 0; i < item.Length; i++)
{
Console.Write($"{item[i]}");
}
Console.WriteLine();
}
}
}
This is the method:
public static ArrayKeeper SortAsc(int[] a, int[] b, int[] c, int[] d)
{
//order arrays
a = a.OrderBy(o => o).ToArray();
b = b.OrderBy(o => o).ToArray();
c = c.OrderBy(o => o).ToArray();
d = d.OrderBy(o => o).ToArray();
a = a.OrderByDescending(o => b.Contains(o)).ToArray();
b = b.OrderByDescending(o => a.Contains(o)).ToArray();
c = c.OrderByDescending(o => (a.Contains(o) && b.Contains(o))).ToArray();
d = d.OrderByDescending(o => (a.Contains(o) && b.Contains(o)) && c.Contains(o)).ToArray();
var resp = new ArrayKeeper();
resp.Arrays.Add(b);
resp.Arrays.Add(a);
resp.Arrays.Add(c);
resp.Arrays.Add(d);
return resp;
}
This is a DTO to help transport data;
public class ArrayKeeper {
public ArrayKeeper()
{
Arrays = new List<int[]>();
}
public List<int[]> Arrays { get; set; }
}
This is the result:
$ dotnet run
Length: 4
47123
47568
47129
41256
Of course it's a POC and is just one way to do something like you want using LINQ, Lists and arrays;
Also I think it will need some kind of validation to be more dynamic;
I have a list of arrays:
List<int[]> a = new List<int[]>();
and i put in it a few arrays
int[] b = new int[3] {1, 2, 3};
int[] c = new int[4] {4, 5, 6, 7};
a.Add(b);
a.Add(c);
how can I print only let's say b[1] out of List a?
You can access it by writing
Console.WriteLine(a[0][1]);
I have a list of integer list like -
List<List<int>> dataList = new List<List<int>> {
new List<int>{ 0, 2, 4, 7 },
new List<int>{ 1, 6, 3 },
new List<int>{ 2, 0, 7, 9 },
new List<int>{ 3, 1, 6 },
new List<int>{ 4, 0, 2 },
new List<int>{ 5, 2, 7 },
};
I want to merge all the list those have duplicates and generate a list of integer list where no values should be common in any list.
The output should be like--
0, 2, 4, 5, 7, 9
1, 3, 6
If you want one single list, then you can do this:
// flatten your list:
var newList = new List<int>();
foreach (var list in output) {
newList.AddRange(list);
}
// make sure every number is only once in that list:
newList.Distinct() // here is linq!
var output = new List<List<int>>();
output.Add(newList);
I've an array sequence 20,40,60,10,30,50. I want to sort this sequence into the following order 60,40,50,20,30,10 in C#.
Any Help? Thanks in advance☺
Very Simple if you have an Array
int[] arr = { 1, 2, 3, 5, 9, 0, 2, 10 };
arr.OrderBy(a => a);
arr.Reverse();
in case of list
List<int> abc = new List<int> { 1, 2, 3, 5, 9, 0, 2, 10 };
abc.Sort();
abc.Reverse();
Just use OrderByDescending of LINQ:
var list = new[] {20, 40, 60, 10, 30, 50};
var newList = list.OrderByDescending(x => x);
Console.WriteLine(string.Join(",", newList)); //60,50,40,30,20,10
You can try this
int[] array = new int[] { 20, 40, 60, 10, 30, 50 };
Array.Sort<int>(array,
new Comparison<int>((element1, element2) => element1.CompareTo(element2)));
to reverse sort
element2.CompareTo(element1)