c# list index 0 showing value as -1 - c#

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

Related

Find First Index of IEnumerable

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.

index out of range checker not working

So I would only like to assign the value to 'originalCOlumName' if there is a value in dataStore.DataSourceDef.Rows[columnIndex].ItemArray[3].ToString(); if it is NULL or out of range, doesnt exist etc...I want to skip this part.
Ive tried looking at another example on Preventing Index Out of Range Error
but NULL checkers didnt work also tried
if(string.IsNullOrEmpty(dataStore.DataSourceDef.Rows[columnIndex].ItemArray[3].ToString())
You would need to check the length of both the Rows and the ItemArray collections to ensure they have enough elements to index into... Remembering that to get element number 3, the array must contain 4 items since numbering starts at 0. This would look something like;
var rowsLength = dataStore.DataSourceDef.Rows.Count;
if (rowsLength >= columnIndex + 1){
var itemArrayLength = dataStore.DataSourceDef.Rows[columnIndex].ItemArray.Count;
if (itemArrayLength >= 4){
var theString = dataStore.DataSourceDef.Rows[columnIndex].ItemArray[3].ToString();
}
}

AddLast() on one list adding to all lists in an array of lists C#

I essentially have the following code:
LinkedList<int>[] listOfNumbers = new LinkedList<int>[6];
int[] someNumbers = new int[6];
for(int index = 0; index < 6; index++)
{
listOfNumbers[index] = new LinkedList<int>();
}
someNumnbers[0] = 0;
someNumnbers[1] = 1;
someNumnbers[2] = 2;
someNumnbers[3] = 3;
someNumnbers[4] = 4;
someNumnbers[5] = 5;
for(int index = 0; index < 6; index++)
{
listOfNumbers[index].AddLast(someNumbers[index]);
}
I expect the following report from the object watch tool in Visual Studio after the first pass of the last loop:
listOfNumbers[0] has 1 element with value 0
listOfNumbers[1] has no elements
listOfNumbers[2] has no elements
listOfNumbers[3] has no elements
listOfNumbers[4] has no elements
listOfNumbers[5] has no elements
But instead I'm curiously finding this:
listOfNumbers[0] has 1 element with value 0
listOfNumbers[1] has 1 element with value 0
listOfNumbers[2] has 1 element with value 0
listOfNumbers[3] has 1 element with value 0
listOfNumbers[4] has 1 element with value 0
listOfNumbers[5] has 1 element with value 0
When I run the last loop to its completion, I get the following:
listOfNumbers[0] has 6 element with values 0,1,2,3,4,5
listOfNumbers[1] has 6 element with values 0,1,2,3,4,5
listOfNumbers[2] has 6 element with values 0,1,2,3,4,5
listOfNumbers[3] has 6 element with values 0,1,2,3,4,5
listOfNumbers[4] has 6 element with values 0,1,2,3,4,5
listOfNumbers[5] has 6 element with values 0,1,2,3,4,5
Versus what I expect to get:
listOfNumbers[0] has 1 element with value 0
listOfNumbers[1] has 1 element with value 1
listOfNumbers[2] has 1 element with value 2
listOfNumbers[3] has 1 element with value 3
listOfNumbers[4] has 1 element with value 4
listOfNumbers[5] has 1 element with value 5
My first guess is I've written something incorrect in the syntax, but I can't seem to figure out what. It obviously seems to be applying the AddLast() to every list in the list array on every pass, but I have no idea why. Any help would be appreciated.
This would happen if you have the same instance of the linked list in each index, if u are actually initialising the linkedlist array as u have shown it it shouldn't be a problem. The same instance means that u instantiated a linked list once into a variable and then assigned that in each of the array index, this would essentially mean that since they are all the same object internally no matter which object u call the addlast method in, it would reflect in each of those items in the array.
I think you're making an array of LinkedLists while you'd want to work with just a LinkedList.
Try to initialize it as a single LinkedList and then add the elements.
Give a look to the example of use to the LinkedList<T> class provided in the documentation:
http://msdn.microsoft.com/it-it/library/he2s3bh7(v=vs.110).aspx
You should rather try doing like below using two for loop. Outer loop is for passing through each list and inner loop is for filling up each list.
for(int i=0; i<6;i++)
{
for(int index = 0; index < 6; index++)
{
listOfNumbers[i].AddLast(someNumbers[index]);
}
}

Putting alternate elements of an array into a combobox

I have a certain number of elements in an array(statsname).
they are in fact as follows
x[1] A_NAME
x[2] A_CATEGORY
x[3] ANOTHER_NAME
x[4] A_CATEGORY
I want the categories in a combobox.
I did
int up =1;
foreach (string things in statsname)
{
//if the stat name doesnot contains TIME
//Only then we add it to the combobox.
if ((Convert.ToString(things[up]) == "CurrentNumber") || (Convert.ToString(things[up]) == "TotalNumber"))
{
tcomboBox1.Items.Add(things[up-1]);
}
up++;
if (up != statsname.Count())
{
tcomboBox1.Items.Add(things[up - 1]);
}
}
However I get an error saying
Array out of bound
Why is it so ?
Where Did I go wrong ?
Problem : you are comapring the character with String, it will never become true.
Solution : if you just want to get all the Categories added in array at odd positions like 1,3,5..etc.,
you can get the odd value out from array and assign the value to combobox.
EDIT : if you want you can get Even value out from array and assign the value to combobox.
Try This:
string [] statsname=new string[] {"A_NAME1","Cat1","A_NAME2","Cat2","A_NAME3","Cat3","A_NAME4","Cat4"};
for(int i=0;i<statsname.Length;i++)
{
if(i%2==0)
tcomboBox1.Items.Add(statsname[i]);
}
An IndexOutOfRangeException has occurred. This happens in C# programs that use array types. This exception will typically occur when a statement tries to access an element at an index greater than the maximum allowable index.
for (int i = 0; i < type.Length; i++)
{
form.comboBox1.Items.Add(type[i]);
}

I have a sorted list of key/value pairs, and want to find the values adjacent to a new key

I have a list of key/value pairs (probably will be using a SortedList) and I won't be adding new values.
Instead I will be using new keys to get bounding values. For example if I have the following key/value pairs:
(0,100) (6, 200), (9, 150), (15, 100), (20, 300)
and I have the new key of 7, I want it to return 200 and 150, because 7 is between 6 and 9.
If I give 15 I want it to return 100 and 100 (because 15 is exactly 15). I want something like a binary search.
Thanks
You can do this with List<T>.BinarySearch:
var keys = new List<int>(sortedList.Keys);
int index = keys.BinarySearch(target);
int lower;
int upper;
if (index >= 0) {
lower = upper = index;
}
else {
index = ~index;
upper = index < keys.Count ? index : index - 1;
lower = index == 0 ? index : index - 1;
}
Console.WriteLine("{0} => {1}, {2}",
target, sortedList[keys[lower]], sortedList[keys[upper]]);
You have to use the return value of List<T>.BinarySearch to get to the boundary values. From msdn, its return value is:
"The zero-based index of item in the sorted List<T>, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count."
Also, for elements that fall below the first or beyond the last, this code "returns" the first and the last twice, respectively. This might not be what you want, but it's up to you to define your boundary conditions. Another one is if the collection is empty, which I didn't address.
Yep, you want exactly binary search -- use the List<t>.BinarySearch method, specifically the overload taking a IComparer second argument (and implement that interface with a simple aux class that just compares keys).

Categories

Resources