I have a method that accepts an IEnumerable as a parameter.
My issue is that this method is sometimes given an array that starts at 1 (instead of 0).
I could just create a list and add the elements of the parameter to it but isn't there a way of just getting the first index?
EDIT 1:
What I mean with "an array that starts at 1" is an array that literally starts at 1, for example:
I cannot access the array "cells" with the line:
cells[0, 0]
This specific array is being read from an Excel range.
EDIT 2:
This isn't the only array that is being given to The method.
The method also receives arrays that start at 0 and it needs to work for all cases.
Normally arrays have a lower bound of 0. However, you can create arrays with different lower bounds. To do that you need to use Array.CreateInstance:
var array = Array.CreateInstance(typeof(string), new[] { 10 }, new[] { 1 });
This will create an one dimensional array with ten elements with a lower bound of 1. Here is how you set the value of the first element:
array.SetValue("first", 1);
In your case you could use code like this to create a two dimensional array with 10 x 20 elements and lower bounds of 1:
var array = (object[,]) Array.CreateInstance(typeof(object), new[] { 10, 20 }, new[] { 1, 1 });
And to get the lower bound of the first dimension you can use GetLowerBound:
var lowerBound = array.GetLowerBound(0);
Specify 1 as the argument to get the lower bound of the second dimension etc. There is also a GetUpperBound method. And in case you don't even know the dimensions of the array you can inspect the Rank property.
I believe this feature mostly exist to support porting old Visual Basic code to Visual Basic .NET and interop with COM automation (e.g. Excel) where arrays often have a lower bound of 1.
I don't understand what do you mean by .
sometimes given an array that starts at 1
The arrays must start at the zero index,
I think you mean to try to filter the values and check if null empty values
you can try the below:
var firstValue = array.First(x => !string.IsNullOrWhiteSpace(x.value));
Or you can remove the first element or any element on a condition
array = array.Skip(0);
UPDATE
When you pass a sub-array to the method, usually it doesn't start at index zero.
So, you can loop on the array to and handle the items after checking if it exists or not using ElementAtOrDefault() Linq method.
for (int i = 0; i < array.length; i++)
{
if(ElementAtOrDefault(i) != null)
// your logic
}
As #MartinLiversage pointed out, there is an overload of Array.CreateInstance allowing to specify a lower bound:
public static Array CreateInstance (Type elementType, int[] lengths, int[] lowerBounds);
You have to cast the unspecific Array to a concrete type, to able to access its elements directly. Example:
var cells =
(int[,])Array.CreateInstance(typeof(int), new[] { ROWS, COLUMNS }, new[] { 1, 1 });
You can get the bounds with cells.GetLowerBound(0) (first dimension) and cells.GetLowerBound(1) (second dimension). There is a corresponding GetUpperBound method. Example:
// Loop through the matrix
for (int i = cells.GetLowerBound(0); i <= cells.GetUpperBound(0); i++) {
for (int j = cells.GetLowerBound(1); j <= cells.GetUpperBound(1); j++) {
// Get an element
var element = cells[i, j];
// Set an element
cells[i, j] = value;
}
}
Or, to get the first element only:
var result = cells[cells.GetLowerBound(0), cells.GetLowerBound(1)];
You can also enumerate the array with foreach. This flattens the array, i.e. it treats the array as if it was one-dimensional.
Note, the LINQ extension method First always returns the first item, irrespective of the lower bounds of the array.
var result = cells.First();
Depending on the need you can use each. Read the link below .
var firstValue = Yourlist.First(x => x.value);
or
var firstValue = Yourlist.FirstOrDefault(x => x.value);
or
var firstValue = Yourlist.Single(x => x.value);
or
var firstValue = Yourlist.SingleOrDefault(x => x.value);
LINQ Single vs First
If you are asking about Excel Interop:
Indexer - Indexer is 1-base:
cells[1,1].Value2 = "something";
IEnumerable - Using Cast and First or FirstOrDefalt:
cells.Cast<dynamic>().FirstOrDefault().Value2 = "something";
IEnumerable - Using GetEnumerator:
var enumerator = cells.GetEnumerator();
enumerator.MoveNext();
((dynamic)enumerator.Current).Value2 = "something";
If you are interested to know about the column index and row index in the sheet, the Column and Row property will show the coordinates in the sheet.
Related
I'm trying to program a Sudoku solver in C# in which I'm using a List of an integer array with all the positions of empty fields, because I need them in my algorithm.
In the progress of solving the Sudoku I need to remove those positions which got filled with a number. But somehow my list with empty positions does not get smaller, when I use the Remove-method.
I will explain my problem with a simplified example:
List<int[]> test1 = new List<int[]>();
test1.Add(new int[] { 0, 0 });
test1.Add(new int[] { 1, 7 });
test1.Remove(new int[] { 1, 7 });
The first line generates the list with my one dimensional integer array (which always consists of two values - one for the column and one for the row-number). The empty positions get added in a method, but in this example I just added them in these two lines.
Later on in my algorithm, I want to remove elements by using the Remove-function similarly to the Add-function. It throws no errors, even while compiling. However, it's not removing anything.
I tried using the RemoveAll-method, although I don't really understand, how it works and therefore didn't find a correct solution for my problem.
By trying out a List of integers (not an integer array) the Remove-method works perfectly, but in the case of an array it doesn't seem to work this way.
Even creating a seperat variable rem
int[] rem = new int[] { 1, 7 };
test1.Remove(rem);
does not work.
I'm a beginner so I don't really know if a List of arrays is the best solution in my case.
bool IntArrayPredicate(int[] element)
{
return element.SequenceEqual(new int[] { 2, 3 });
}
List<int[]> listOfIntArray = new List<int[]>();
listOfIntArray.Add(new int[] { 0, 0 });
listOfIntArray.Add(new int[] { 1, 7 });
listOfIntArray.Add(new int[] { 2, 3 });
listOfIntArray.RemoveAll(element => element.SequenceEqual(new int[] { 1, 7 })); //It Works!. Using lambda expresion. Remove by Comparing sequences that match equals.
int[] toRemove = listOfIntArray[0];
listOfIntArray.Remove(toRemove); //It works!. Remove element by exact reference.
listOfIntArray.Remove(new int[] { 2, 3 }); // Not working / References are different.
listOfIntArray.RemoveAll(IntArrayPredicate); // It works!. Same as using lambda but using method reference.
Console.WriteLine($"{nameof(listOfIntArray)} has {listOfIntArray.Count()} elements"); // Yup. 0 elements.
The reason you're not able to remove items from your list using the Remove method is that you're storing reference types in the List, but creating new references when trying to remove an item. Because reference types by default use a reference comparison (not a comparison of their fields) to determine equality, you won't be able to remove items in that way.
One way to resolve this is to create a reference to each object in the List<int[]> outside of the list creation itself. This way, you can use the existing reference as an argument to the Remove method, and, because it's referring to the same object that was added to the list, it will match and be removed:
// Here we have 'item1' and 'item2' that refer to the location of different int[]
int[] item1 = new int[] { 0, 0 };
int[] item2 = new int[] { 1, 7 };
// And now we use those references to add the int[] items to our list
List<int[]> test1 = new List<int[]>();
test1.Add(item1);
test1.Add(item2);
// Finally, we can remove an item using the same reference that we used to add it
test1.Remove(item2);
This is very clunky, however, since we now need to maintain an individual reference for every item in our list as well as the list itself.
Another way to resolve this would be to search for the item we want to remove using our own equality algorithm (rather than relying on the default equality that Remove uses). We can use FirstOrDefault to search for the first item that has a length of 2 and whose values match those that we want. It will return a reference to the item if it's found, or null if it's not found. We can use IndexOf to get the index of the item (or -1 if it's not found), and then pass that index to the RemoveAt method to remove it:
List<int[]> test1 = new List<int[]>();
test1.Add(new int[] { 0, 0 });
test1.Add(new int[] { 1, 7 });
int indexToRemove = test1.IndexOf(test1.FirstOrDefault(item =>
item.Length == 2 && item[0] == 1 && item[1] == 7));
if (indexToRemove >= 0) test1.RemoveAt(indexToRemove);
As you can see, what you're trying to do isn't super easy. As a suggestion to help you think about the problem in a different way, you might consider using a 2-dimensional array to store the sudoku grid. Normally we store the row in the first dimesion and the column in the second dimension:
int[,] grid = new int[9, 9];
You could potentially create a few of these, one to represent the puzzle solution, one to represent the puzzle shown to the user's (with just their guesses), maybe even one to store user's "notes" (if you allow them to tag a cell with possible values before committing to a guess), though that would likely need to be a string[,] or an int[,][].
Then the typical way to loop through the grid would be something like:
for (int row = 0; row < 9; row++)
{
for (int col = 0; col < 9; col++)
{
// Do something with the cell at 'row' 'col' here
// Set a value for this cell
grid[row, col] = row + col;
// Report the value of a cell
Console.WriteLine($"The value at row {row} and column {col} is {grid[row, col]}");
}
}
I am trying to write an implementation on C# of Subsets pattern read here 14 Patterns to Ace Any Coding Interview Question:
It looks obvious but confuses me. My research says me it should be implemented via Jagged Arrays (not Multidimensional Arrays). I started:
int[] input = { 1, 5, 3 };
int[][] set = new int[4][];
// ...
Could someone help with 2, 3 and 4 steps?
The instructions provided seem to lend themselves more to a c++ style than a C# style. I believe there are better ways than manually building arrays to get a list of subsets in C#. That said, here's how I would go about implementing the instructions as they are written.
To avoid having to repeatedly grow the array of subsets, we should calculate its length before we allocate it.
Assuming n elements in the input, we can determine the number of possible subsets by adding:
All subsets with 0 elements (the empty set)
All subsets with 1 element
All subsets with 2 elements
...
All subsets with n-1 elements
All subsets with n elements (the set itself)
Mathematically, this is the summation of the binomial coefficient. We take the sum from 0 to n of n choose k which evaluates to 2^n.
The jagged array should then contain 2^n arrays whose length will vary from 0 to n.
var input = new int[] { 1, 3, 5 };
var numberOfSubsets = (int)Math.Pow(2, input.Length);
var subsets = new int[numberOfSubsets][];
As the instructions in your article state, we start by adding the empty set to our list of subsets.
int nextEmptyIndex = 0;
subsets[nextEmptyIndex++] = new int[0];
Then, for each element in our input, we record the end of the existing subsets (so we don't end up in an infinite loop chasing the new subsets we will be adding) and add the new subset(s).
foreach (int element in input)
{
int stopIndex = nextEmptyIndex - 1;
// Build a new subset by adding the new element
// to the end of each existing subset.
for (int i = 0; i <= stopIndex; i++)
{
int newSubsetLength = subsets[i].Length + 1;
int newSubsetIndex = nextEmptyIndex++;
// Allocate the new subset array.
subsets[newSubsetIndex] = new int[newSubsetLength];
// Copy the elements from the existing subset.
Array.Copy(subsets[i], subsets[newSubsetIndex], subsets[i].Length);
// Add the new element at the end of the new subset.
subsets[newSubsetIndex][newSubsetLength - 1] = element;
}
}
With some logging at the end, we can see our result:
for (int i = 0; i < subsets.Length; i++)
{
Console.WriteLine($"subsets[{ i }] = { string.Join(", ", subsets[i]) }");
}
subsets[0] =
subsets[1] = 1
subsets[2] = 3
subsets[3] = 1, 3
subsets[4] = 5
subsets[5] = 1, 5
subsets[6] = 3, 5
subsets[7] = 1, 3, 5
Try it out!
What I find easiest is translating the problem from a word problem into a more logical one.
Start with an empty set : [[]]
So the trick here is that this word problem tells you to create an empty set but immediately shows you a set that contains an element.
If we break this down into arrays instead(because I personally find it more intuitive) we can translate it to:
Start with an array of arrays, who's first element is an empty array. (instead of null)
So basically
int[][] result = new int[]{ new int[0] };
Now we have somewhere to start from, we can start to translate the other parts of the word problem.
Add the First Number (1) to all existing subsets to create subsets: [[],[1]]
Add the Second Number (5) to all existing subsets ...
Add the Third Number (3) to all existing subsets ...
There's a lot of information here. Let's translate different parts
Add the 1st Number ...
Add the 2nd Number ...
Add the nth Number ...
The repetition of these instructions and the fact that each number 1, 5, 3 matches our starting set of {1, 5, 3} tells us we should use a loop of some kind to build our result.
for(int i = 0; i < set.Length; i++)
{
int number = set[i];
// add subsets some how
}
Add the number to all existing subsets to create subsets: [[],[1]
A couple things here stand out. Notice they used the word Add but provide you an example where the number wasn't added to one of the existing subsets [[]] turned into [[],[1]]. Why is one of them still empty if we added 1 to all of them?
The reason for this is because when we create the new subsets and all their variations, we want to keep the old ones. So we do add the 1 to [](the first element) but we make a copy of [] first. That way when we add 1 to that copy, we still have the original [] and now a brand new [1] then we can combine them to create [[],[1]].
Using these clues we can decipher that Add the number to all existing subsets, actually means make copies of all existing subsets, add the number to each of the copies, then add those copies at the end of the result array.
int[][] result = new int[]{ new int[0] };
int[] copy = result[0];
copy.Append(1); // pseudo code
result.Append(copy); // pseudo code
// result: [[],[1]]
Let's put each of those pieces together and put together the final solution, hopefully!
Here's an example that I threw together that works(at least according to your example data).
object[] set = { 1, 5, 3 };
// [null]
object[][] result = Array.Empty<object[]>();
// add a [] to the [null] creating [[]]
Append(ref result, Array.Empty<object>());
// create a method so we can add things to the end of an array
void Append<T>(ref T[] array, T SubArrayToAdd)
{
int size = array.Length;
Array.Resize(ref array, size + 1);
array[size] = SubArrayToAdd;
}
// create a method that goes through all the existing subsets and copies them, adds the item, and adds those copies to the result array
void AddSubsets(object item)
{
// store the length of the result because if we don't we will infinitely expand(because we resize the array)
int currentLength = result.Length;
for (int i = 0; i < currentLength; i++)
{
// copy the array so we don't change the original
object[] previousItemArray = result[i]; // []
// add the item to it
Append(ref previousItemArray, item); // [1]
// add that copy to the results
Append(ref result, previousItemArray); // [[]] -> [[],[1]]
}
}
// Loop over the set and add the subsets to the result
for (int i = 0; i < set.Length; i++)
{
object item = set[i];
AddSubsets(item);
}
I am creating a basic program in unity where I check a list array index carry out a certain action depending on the value, I then increment the index.The problem I am having is that the array always stores in index 0 and always equals -1.
public class numGen(){
int val;
int i = 0;
System.Random rnd = new System.Random();
val = rnd.Next(1, 5);
arrayList.Add(val);
Debug.Log("val"+val);
Debug.Log("array"+arrayList.IndexOf(i));
if (arrayList.IndexOf(i) == 1)
{
Debug.Log("action1");
i++;
}
else if (arrayList.IndexOf(i) == 2)
{
Debug.Log("action2");
i++;
}
//and so on
}
I have used debug in the log, so val will output a expected value, e.g. 2, gets added into the array when I check the value stored in the index it's -1.
Not sure how or why the int value is changing.
The problem here is a misunderstanding how ArrayList and IndexOf() works.
ArrayList.IndexOf()
Searches for the specified Object and returns the zero-based index of the first occurrence within the range of elements in the ArrayList that starts at the specified index and contains the specified number of elements.
So your exception comes from:
The zero-based index of the first occurrence of value within the range of elements in the ArrayList that starts at startIndex and contains count number of elements, if found; otherwise, -1.
I think your are looking for something like this:
ArrayList.Item()
Gets or sets the element at the specified index.
Also it's possible to
This property provides the ability to access a specific element in the collection by using the following syntax: myCollection[index].
An example in your case:
if (arrayList[i] == 1)
{
// if true..
}
arrayList.IndexOf(i) gives the index of any element with the value of i. If you want the value at index i, you must use arrayList[I] instead.
IndexOf gives the index of the value you give. If there is no equal value found in the array it returns -1
ArrayList arr = new ArrayList();
arr.Add(5);
arr.Add(2);
var isMinusOne = arr.IndexOf(0); //Is -1
var isZero = arr.IndexOf(5); //Is 0
I would like to add a column of zeros to all of my double[] in my List<List<double[]>>().
The length of the double[] is currently 2 and I would like to have doubles[] of length 3. The zero should always be in the third position, for example:
double[50, 75] // double [50,75,0]
This has to be done in all of the List<double[]> within List<List<double[]>>.
Is there a short way to do this?
There is a short way of doing this in terms of lines of code, but the number of allocations and copying is equal to the number of arrays in the original list:
var res = orig.
Select(list => list
.Select(array => array.Concat(new[] {0.0}).ToArray())
.ToList()
).ToList();
Demo.
because you want to extend the array in the source list you need to manipulate them in the internal list:
foreach (var list in rootList)
{
for (var i = 0; i < list.Count; i++)
{
var actor = list[i];
list[i] = new double[actor.Length + 1]; // all elements will be 0....
Array.Copy(list[i], actor, actor.Length); //just add the prev elements
}
}
the above operation will apply the change on all pointers to List<List<double[]>>.
if you don't want to make the change on all pointer to rootList, #dasblinkenlight answer is good enough.
I need to get an array containing reversed alternate elements of the original array.
For example: an array containing elements {12,56,67}.
I need to get an array containing {67,12}
(reversing array to get {67,56,12} then take alternate elements means {67,12})
I need to do this in c#
This won't be the shortest answer you'll get, but it seems fairly optimised to me.
int[] rgIn = new int[]{0,1,2,3,4,5};
int[] rgOut = new int[rgIn.Length / 2];
int ixOut = 0;
for (int ixIn = rgIn.Length - 2; ixIn >= 0; ixIn -= 2)
{
rgOut[ixOut++] = rgIn[ixIn];
}
If you're using C# 3, try this:
int[] array = {1,2,3,4,5,6};
var x = array.Reverse().Where( (n,i) => i % 2 !=0);
Where is an extension method (new in C# 3.0) which forms part of a language feature called LINQ. It filters a sequence based on a predicate. In the sample above, n is the element of the sequence and i is the zero based index of the element in the sequence. Both are strongly typed. The predicate i%2!=0 is saying that the index of the element is not directly divisible by 2, so what we are saying is reverse the list and select the odd elements from it.
Not the most efficient solution, but short and concise.