Zero out subarrays if sums don't match - c#

Given two Lists of integer arrays of the form:
genData = { {1,2,3,4}, {1,2,3,4}, {1,2,3,4}, {1,2,3,4}};
orgData = {{1,2,3,4}, {1,2,3,4}, {2,4,6,8}, {1,2,3,4}};
I'd like to determine if the sum of two subarrays at the same index in both lists don't match. If the sums match, do nothing. If the sums don't match, convert every integer in both subarrays into a 0.
For example, in the two lists above the subarrays at index 2 have a non-matching sum (10 vs 20). I'd like to convert the lists to
genData = { {1,2,3,4}, {1,2,3,4}, {0,0,0,0}, {1,2,3,4} };
orgData = { {1,2,3,4}, {1,2,3,4}, {0,0,0,0}, {1,2,3,4} };
I'm trying to first create a list if sums by trying
var genDataSum = genDataList.ForEach(x => x.Sum());
But obviously, that's throwing up errors..."Cannot assign void to an implicitly typed value".
Any help or guidance will be greatly appreciated.

You need to use select to get the sum. list.foreach works like normal for loop.
List<int[]> genData = new List<int[]>
{
new int[] { 1, 2, 3, 4 },
new int[] { 1, 2, 3, 4 },
new int[] { 1, 2, 3, 4 },
new int[] { 1, 2, 3, 4 }
};
List<int[]> orgData = new List<int[]>
{
new int[] { 1, 2, 3, 4 },
new int[] { 1, 2, 3, 4 },
new int[] { 2, 4, 6, 8 },
new int[] { 1, 2, 3, 4 }
};
var sumsGenData = genData.Select(a => a.Sum()).ToList();
var sumsOrgData = orgData.Select(a => a.Sum()).ToList();
for (int i = 0; i < sumsGenData.Count; i++)
{
if (sumsGenData[i] != sumsOrgData[i])
{
orgData[i] = new int[] { 0, 0, 0, 0 };
}
}

ForEach doesn't return anything. Use Select.
var orgData = { {1,2,3,4}, {1,2,3,4}, {0,0,0,0}, {1,2,3,4} };
var sums = orgData.Select( a => a.Sum() );

Related

Combinations without repetitions with must included in the combos

I have 2 list of ints and I need a list of all possible combinations without repetitions of 5 numbers. But it also needs to include all the ints from another list.
Example:
var takeFrom = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var mustInclude = new List<int> { 1, 3, 5 };
I have been using KwCombinatorics but it takes ages to finish. And almost 80% of the result is useless because it doesn't contain the ints from the mustInclude list.
Example of output:
var result = new List<int>
{
{ 1, 3, 5, 9, 10 },
{ 1, 3, 5, 8, 7 },
{ 1, 3, 5, 6, 9 },
}
It doesn't have to be in this order, as long as it doesn't contain repetitions.
Borrowing GetAllCombos from this Question, and using the idea from #juharr, I believe the following code gives you the results you are looking for.
List<int> takeFrom = new List<int> { 2, 4, 6, 7, 8, 9, 10 };
List<int> mustInclude = new List<int> { 1, 3, 5 };
protected void Page_Load(object sender, EventArgs e)
{
List<List<int>> FinalList = new List<List<int>>();
FinalList = GetAllCombos(takeFrom);
FinalList = AddListToEachList(FinalList, mustInclude);
gvCombos.DataSource = FinalList;
gvCombos.DataBind();
}
// Recursive
private static List<List<T>> GetAllCombos<T>(List<T> list)
{
List<List<T>> result = new List<List<T>>();
// head
result.Add(new List<T>());
result.Last().Add(list[0]);
if (list.Count == 1)
return result;
// tail
List<List<T>> tailCombos = GetAllCombos(list.Skip(1).ToList());
tailCombos.ForEach(combo =>
{
result.Add(new List<T>(combo));
combo.Add(list[0]);
result.Add(new List<T>(combo));
});
return result;
}
private static List<List<int>> AddListToEachList(List<List<int>> listOfLists, List<int> mustInclude)
{
List<List<int>> newListOfLists = new List<List<int>>();
//Go through each List
foreach (List<int> l in listOfLists)
{
List<int> newList = l.ToList();
//Add each item that should be in all lists
foreach(int i in mustInclude)
newList.Add(i);
newListOfLists.Add(newList);
}
return newListOfLists;
}
protected void gvCombos_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
List<int> drv = (List<int>)e.Row.DataItem;
Label lblCombo = (Label)e.Row.FindControl("lblCombo");
foreach (int i in drv)
lblCombo.Text += string.Format($"{i} ");
}
}
GetAllCombos gives you all the combinations without the numbers required by all Lists, and then the second AddListToEachList method will add the required numbers to each List.
As already suggested in the comments, you can remove the three required numbers from the list and generate the combinations of two instead of five.
Something like this:
takeFrom = takeFrom.Except(mustInclude).ToList();
listOfPairs = KwCombinatorics(takeFrom, 2);
result = listOfPairs.Select(pair => mustInclude.Concat(pair).ToList()).ToList();

c# - How to remove from List using LINQ the elements with X times of repetition?

I have "myList" of int[].
int[] linha1 = { 1, 2, 2, 2, 3 };
int[] linha2 = { 1, 2, 2, 3, 4 };
int[] linha3 = { 1, 2, 3, 4, 5 };
List<int[]> myList = new List<int[]>();
myList.Add(linha1);
myList.Add(linha2);
myList.Add(linha3);
I want to remove from myList the elements with numbers repeating more than twice.
Ex.: only "linha1" would be removed because the number "2" repeats 3 times.
Is there a way using LINQ?
Just for the challenge try this
var linhaTokeep = myList.Where(l =>l.GroupBy(i => i).All(v => v.Count() <= 2));
foreach (var b in linhaTokeep)
{
Console.WriteLine(string.Join(',' ,b));
}

c# searching a list of integer arrays

I have a list of int arrays.
How do I search for a specific int[]?
Example:
var listIntArray = new List<int[]>();
listIntArray.Add(new int[] { 1, 2, 3, 4, 5, 6 });
var array1 = new int[] { 1, 2, 3, 4, 5, 6 };
bool contains1 = listIntArray.Contains(array1);
//--> should be true
var array2 = new int[] { 4, 5, 6 };
bool contains2 = listIntArray.Contains(array2);
//--> should be false
You could do this with LINQ.
bool result = listIntArray.Any(arr => arr.SequenceEqual(array1));

How to get the row or columns of two dimensional array

I am wondering how to get the row of the two dimensional array like
int[3,3] a = ****
I tried a[0], but it failed. anyway to get the rwo array?
Two-dimensional array is not array of arrays. If you want to get 'row', then you need to get all items from array which have same value of some dimension. E.g. if you are getting all values from first dimension:
int[,] array = new int[4, 3] {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 }
};
for(int i = 0; i <= array.GetUpperBound(1); i++)
Console.WriteLine(array[0,i]); // getting all items from first dimension
You can put all these items to array:
int rowIndex = 0;
int[] row = Enumerable.Range(0, array.GetUpperBound(1) + 1)
.Select(i => array[1, i])
.ToArray();
Another option will be using jagged-array instead of two-dimensional array:
int[][] array = new []{
new[] { 1, 2, 3 },
new[] { 4, 5, 6 },
new[] { 7, 8, 9 },
new[] { 10, 11, 12, 13, 14, 15 }
};
It's an array of arrays. But note that inner arrays can have different size. Getting some 'row' will look like
int[] row = array[0];

Find index of an array in List of arrays in C#

If you had a List of arrays like:
List<int[]> ListOfArrays = new List<int[]>();
ListOfArrays.Add(new int[] { 1, 1 });
ListOfArrays.Add(new int[] { 2, 1 });
How would you find the index of { 2, 1} in the List?
I do not want to use an iteration loop. I would like a concise method like the one suggested by PaRiMaL RaJ in Check if string array exists in list of string:
list.Select(ar2 => arr.All(ar2.Contains)).FirstOrDefault();
(the above code will return true if members of a given string array exist in a list of string arrays)
var myArr = new int[] { 2, 1 };
List<int[]> ListOfArrays = new List<int[]>();
ListOfArrays.Add(new int[] { 1, 1 });
ListOfArrays.Add(new int[] { 4, 1 });
ListOfArrays.Add(new int[] { 1, 1 });
ListOfArrays.Add(new int[] { 2, 1 });
int index = ListOfArrays.FindIndex(l => Enumerable.SequenceEqual(myArr, l));
You can use the SequenceEqual method for this. See MSDN: https://msdn.microsoft.com/en-us/library/vstudio/bb348567(v=vs.100).aspx
You can try this:
List<int[]> ListOfArrays = new List<int[]>();
ListOfArrays.Add(new int[] { 1, 1 });
ListOfArrays.Add(new int[] { 2, 1 });
var chk = ListOfArrays.FindIndex(e => (e.SequenceEqual(new int[] { 2, 1 })));

Categories