How to Access List's elements in c# - c#

I have a list of lists like : List<List<int>> a ;
How can I initialize it like this:
<2 1> <3 0> <5 1>
I mean the list "a" has three lists that each one has 2 elements
And then how can i access each element or change the value of them?

You can initialise your list like this:
var list = new List<List<int>>()
{
new List<int>() {2, 1 },
new List<int>() {3, 0 },
new List<int>() {5, 1 }
};
And then you can access each element like this:
var x = list[0][1]; // 1
var y = list[1][0]; // 3
And you can access each inner list like this:
var inner = list[0];// List<int> (2, 1)
And you can update the list like this:
list[0][1] = 42;
or
list[0] = new List<int>() { 10, 11 };
EDIT: How to initialise the list with 10 lists of 1, 1
var list = new List<List<int>>();
for(var i=0;i<10;i++)
{
list.Add(new List<int>() {1, 1});
};

he needs a list of 3 lists of 2 elements each.
List<List<int>> a = new List<List<int>> { new List<int>() { 2, 1 }, new List<int>() { 3, 0 }, new List<int>() { 5, 1 } };

Related

Partition lists of integers based on unique sets of numbers they contain

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);

Remove the end of a list based on the start of another list

I have two lists:
var list1 = new List<int> { 0, 1, 2 };
var list2 = new List<int> { 1, 2, 3 };
I want to be able to check if the ending chunk of list1 is present at the start of list2. After that I want to delete one of the chunks from any of the lists, merging both into a third list (sequentially, list1 + list2).
var list3 = list1.Something(list2);
//Returns 0,1,2,3 instead of 0,1,2,1,2,3
There's another problem, one list can be smaller than the other, such as:
0,1,2,3 <-- 2,3,4 = 0,1,2,3,4
5,6 <-- 6,7,8 = 5,6,7,8
And of course, both lists can be different:
0,1,2 <-- 5,6,7 = 0,1,2,5,6,7
[empty] <-- 1,2 = 1,2
Is there any method provided by .Net Framework that allows me to do that?
If not, could you help me create one?
The end and start can only "kill" each other if they are sequentially equal.
Example, if list1 ends in 1,2 and list2 starts with 2,1 they are not equal.
So, Distinct() is not helpful.
My use case:
private List<int> Cut(this List<int> first, List<int> second)
{
//Code
return new List<int>();
}
internal List<int> MergeKeyList()
{
var keyList = new List<int>() {0, 1, 2};
var newList = new List<int>() {1, 2, 3};
return keyList.InsertRange(keyList.Count, keyList.Cut(newList));
}
Would be much more efficient with for loops .. but whatever:
keyList.TakeWhile((_, i) => !keyList.Skip(i).SequenceEqual(newList.Take(keyList.Count - i)))
.Concat(newList)
Try this:
void Main()
{
var keyList = new List<int>() {0, 1, 2};
var newList = new List<int>() {1, 2, 3};
var result = keyList.Cut(newList);
}
public static class Ex
{
public static List<int> Cut(this List<int> first, List<int> second)
{
var skip =
second
.Select((x, n) => new { x, n })
.Where(xn => xn.x == first.Last())
.Where(xn =>
first
.Skip(first.Count - xn.n - 1)
.SequenceEqual(second.Take(xn.n + 1)))
.Reverse()
.Select(xn => xn.n + 1)
.FirstOrDefault();
return first.Concat(second.Skip(skip)).ToList();
}
}
result becomes:
Also:
{ 0, 1, 2 } & { 1, 2, 1, 2, 3 } => { 0, 1, 2, 1, 2, 3 }
{ 0, 1, 2, 1 } & { 1, 2, 1, 2, 3 } => { 0, 1, 2, 1, 2, 3 }

How to find complex permutations based on and/or rules of lists of numbers, C#/Linq

The current problem is that the code works, but it gets exponentially slower as more combinations are passed in. (The calculation takes > 5 seconds after 15 combinations are passed in.) I need to be able to pass in up to 100 combinations and still get a result back that takes less than 2 seconds.
I'm betting that a Linq query could solve this?
What I want to achieve:
{1, 2, 3} + {1, 5, 26, 40} = 12 combinations:
[1,1]
[1,5]
[1,26]
[1,40]
[2,1]
[2,5]
[2,26]
[2,40]
[3,1]
[3,5]
[3,26]
[3,40]
However, this example above only includes 2 combination sets. I should be able to pass in any number of combination sets.
The closest thing that looks like it is similar to what I want as an end result, due to being fast and efficient, is a linq query that handles most or all of the logic within it. Example: Getting all possible combinations from a list of numbers
public IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list)
{
return from m in Enumerable.Range(0, 1 << list.Count)
select
from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i];
}
Example of working code:
[Test]
public void StackOverflowExample_Simple()
{
var list1 = new List<int>() { 1, 2, 3 };
var list2 = new List<int>() { 1, 5, 26, 40 };
var myListsOfNumberCombinations = new List<List<int>>() { list1, list2 };
var results = GetAllPossibleCombinations(myListsOfNumberCombinations);
Assert.AreEqual(12, results.Count());
StringBuilder sb = new StringBuilder();
foreach (var result in results)
{
foreach (var number in result.OrderBy(x => x))
{
sb.Append(number + ",");
}
sb.Append("|");
}
string finalResult = sb.ToString().Replace(",|", "|");
Assert.AreEqual(finalResult, "1,1|1,5|1,26|1,40|1,2|2,5|2,26|2,40|1,3|3,5|3,26|3,40|");
}
[Test]
public void StackOverflowExample_TakesALongTime()
{
var list1 = new List<int>() { 1, 2, 3 };
var list2 = new List<int>() { 4, 5 };
var list3 = new List<int>() { 1, 6 };
var list4 = new List<int>() { 2, 5 };
var list5 = new List<int>() { 1, 3, 55, 56 };
var list6 = new List<int>() { 3, 4, 7, 8, 9 };
var myListsOfNumberCombinations = new List<List<int>>() { list1, list2, list3, list4, list5, list1, list1, list1, list3, list4, list4, list5, list6, list6, list2 };
DateTime startTime = DateTime.Now;
var results = GetAllPossibleCombinations(myListsOfNumberCombinations);
Assert.AreEqual(4147200, results.Count());
var duration = DateTime.Now.Subtract(startTime).TotalSeconds;
//duration = about 4 or 5 seconds
Assert.Less(duration, 10); //easy place to put a breakpoint
}
public IEnumerable<IEnumerable<int>> GetAllPossibleCombinations(List<List<int>> combinationSets)
{
List<List<int>> returnList = new List<List<int>>();
_RecursiveGetMoreCombinations(
ref returnList,
new List<int>(),
combinationSets,
0);
return returnList;
}
private void _RecursiveGetMoreCombinations(
ref List<List<int>> returnList,
List<int> appendedList,
List<List<int>> combinationSets,
int index)
{
var combinationSet = combinationSets[index];
foreach (var number in combinationSet)
{
List<int> newList = appendedList.AsEnumerable().ToList();
newList.Add(number);
if (combinationSets.Count() == index + 1)
{
returnList.Add(newList);
}
else
{
_RecursiveGetMoreCombinations(
ref returnList,
newList,
combinationSets,
index + 1);
}
}
}
Can you not just do permutations of the first and third sets (the OR sets) and then place '45' (the AND set), or whatever the static numbers are, in between those numbers?
You don't need to include 4 and 5 (in this example) in the permutation logic if they are always going to be present.

Linq compare 2 lists of arrays

I would like to compare 2 lists of arrays. Let's take for instance this example:
List<int[]> list1 = new List<int[]>() { new int[4] { 1, 2, 3, 4 }, new int[4] { 1, 2, 3, 5 } };
List<int[]> list2 = new List<int[]>() { new int[2] { 1, 2 }, new int[2] { 3, 4 }, new int[2] { 3, 5 } };
I would like to know for each element in list1 to calculate for every element in list 2 how many common elements they have.
Ex. 1,2,3,4 compared with 1,2 will result to 2 matching elements.
1,2,3,4 compared with 3,5 will result to 1 matching element.
This is not duplicated as I don't wish to compare regular lists. I wish to see for each record in list1 how many items from list2 contain how many common items.
List<int[]> list1 = new List<int[]>() { new int[4] { 1, 2, 3, 4 }, new int[4] { 1, 2, 3, 5 } };
List<int[]> list2 = new List<int[]>() { new int[2] { 1, 2 }, new int[2] { 3, 4 }, new int[2] { 3, 5 } };
var results = list1.Select(x => list2.Select(y => y.Intersect(x).Count()).ToList()).ToList();
Result contains following data: [ [ 2, 2, 1 ], [ 2, 1, 2 ] ]
You can use Enumerable.Intersect to find out common items of first found in second list.
var commonList = list1.Intersect(list2);
The intersection of two sets A and B is defined as the set that
contains all the elements of A that also appear in B, but no other
elements
Edit Since you have array as element of list you have to go through each list item.
List<int[]> list1 = new List<int[]>() { new int[4] { 1, 2, 3, 4 }, new int[4] { 1, 2, 3, 5 } };
List<int[]> list2 = new List<int[]>() { new int[2] { 1, 2 }, new int[2] { 3, 4 }, new int[2] { 3, 5 } };
List<int[]> list3 = new List<int[]>();
for (int i = 0; i < list1.Count; i++)
{
list3.Add(list1[i].Intersect(list2[i]).ToArray());
}
You'd do something like this:
var results =
from x in list1.Select((array, index) => new { array, index })
from y in list2.Select((array, index) => new { array, index })
select new
{
list1_index = x.index,
list2_index = y.index,
count = x.array.Intersect(y.array).Count()
};
foreach(var r in results)
{
Console.WriteLine("({0}, {1}) have {2} item(s) in common.", r.list1_index, r.list2_index, r.count);
}
// (0, 0) have 2 item(s) in common.
// (0, 1) have 2 item(s) in common.
// (0, 2) have 1 item(s) in common.
// (1, 0) have 2 item(s) in common.
// (1, 1) have 1 item(s) in common.
// (1, 2) have 2 item(s) in common.
var commons = list1.Select(x => list2.Select(x.Intersect).ToArray()).ToArray();
Console.WriteLine(commons[0][0]); // Commons between list1[0] and list2[0]
Console.WriteLine(commons[0][1]); // Commons between list1[0] and list2[1]
Console.WriteLine(commons[3][0]); // Commons between list1[3] and list2[0]
Console.WriteLine(commons[3][0].Length); // Number of commons between [3] and [0]
Accourding to ur requirement, I think in C# there isnt such inbuild function in list which do exactly what you want but following function return exactly what you required in resultList. Hope this help you.
private List<int> MatchList()
{
List<int[]> list1 = new List<int[]>() { new int[4] { 1, 2, 3, 4 }, new int[4] { 1, 2, 3, 5 } };
List<int[]> list2 = new List<int[]>() { new int[2] { 1, 2 }, new int[2] { 3, 4 }, new int[2] { 3, 5 } };
List<int> resultList = new List<int>();
for (int i = 0; i < list1.Count; i++)
{
for (int j = 0; j < list2.Count; j++)
{
if (i == j)
{
int result = 0;
foreach (int list1Element in list1[i])
{
foreach (int list2Element in list2[j])
{
if (list1Element == list2Element)
{
result +=1;
}
}
}
resultList.Add(result);
}
}
}
return resultList;
}

C# Creating an array of arrays

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 }
};

Categories

Resources