I am using an int array to hold a long list of integers. For each element of this array I want to check if it is 1, if so do stuff relevant to 1 only, else if it is a 2, do other stuff relevant to 2, and so forth for each value stored in the array. I came up with the code below but it isn't working as expected, is there something I am missing? What is happening is that only the first value of the array is being considered.
int[] variable1 = MyClass1.ArrayWorkings();
foreach (int i in variable1)
{
if (variable1[i] == 1)
{
// arbitrary stuff
}
else if (variable1[i] ==2)
{
//arbitrary stuff
}
}
The i in your foreach loop holds the actual element value from the array in each iteration, not the index. In your particular code sample, your array probably holds only zeroes, which is why you're only getting the first element (you're always using index 0). Hence, you should check i rather than variable1[i].
If you are going to check against various integer constants, a switch expression is more suitable, BTW:
foreach (int i in variable1) {
switch (i) {
case 1:
// arbitrary stuff
break;
case 2:
// arbitrary stuff
break;
}
}
switch/case saves you some writing; if you ever pull your values from anywhere else than from i, you can simply change the (i) part in the switch statement, and moreover, switch might be evaluated by the compiler more efficiently than the chained if-else statements.
Note: You will not be able to directly change array values in the foreach loop, as you cannot assign anything to i. If you need to assign new array values, you'll have to
count yourself with an additional variable while still using foreach or
use another loop such as for and retrieve the item at the current index yourself.
You're trying to do something that doesn't make sense. To see how it works, take a simple example, an array with values: 9, 4, 1.
If you try to run your code on this sample array, you'll get an error:
foreach (int i in variable1)
{
if (variable1[i] == 1) // the item i is 9.
// But variable[i] means, get the value at position #9 in the array
// Since there are only 3 items in the array, you get an Out Of Range Exception
{
// arbitrary stuff
}
{
Instead, this is what you need:
foreach (int i in variable1) // i will be 9, then 4, then 1)
{
if (i == 1)
{
// arbitrary stuff
}
// ... etc
}
The alternative is to use a for loop, which would give you the indices 0, 1, and 2, like this:
for (int i=0 ; i<=variable1.Length ; i++) // i will be 0, 1, 2
// variable[i] will be 9, 4, 1
{
if (variable1[i] == 1)
{
// stuff
}
// ... etc
}
Write like this instead:
foreach (int i in variable1) {
if (i == 1) {
....
The i you fetched is not the index but the value. So check i with 1 or 2.
If you were using for loop then your inner code would have worked perfectly.
int[] variable1 = MyClass1.ArrayWorkings();
foreach (int i in variable1)
{
switch(i)
{
case 1:
// arbitrary stuff
break;
case 2:
//arbitrary stuff
break;
}
}
Try using switch case. Much faster than normal if-else.
Related
I am trying to filter a list of int based on multiples of a specific number, but I am not sure how to do this. I have searched this forum and found nothing related, but apologies in advance if I'm wrong.
Here is my code:
int val = 28;
List<int> divisible = new List<int>();
for (int i = 1; i <= val; i++) {
divisible.Add(i);
}
foreach(var d in divisible)
{
if(val % d == 0)
{
// do something
}
else
{
// get rid of all multiples of the number that "val" is not divisible by
}
}
Basically, this code should create a divisible list from 1 to 28. If val is divisible by one of the numbers in the list, thats fine, but if it falls into else, I want to be able to filter out all multiples of that number out of the current list we are looping through.
The next number that wouldn't be divisible would be 3 in this example, so in the else get rid of 6, 9, 12, ... etc.
Your code is fine, but you're just missing the actual code to remove the item. But there is a caveat: You cannot modify a list when you are looping through it using foreach. There are a couple ways to handle that:
Depending on your requirements, maybe just don't add them in the first place. Move your val % d == 0 condition into the for loop that adds the values, and just don't add the values that are divisible by d.
Make a new list (List<int> toRemove) where you keep track of all the values you need to remove. After you're done the foreach loop, loop through your toRemove list and use divisible.Remove(value) to remove those.
Change your foreach to a for loop, which will allow you to use divisible.RemoveAt(i). But you will have to make sure you don't skip a value on the next iteration of the for loop (since removing a value changes the size of the list).
I agree with Gabriel. You cannot alter a underlying enumeration while traversing it with with foreach. The easiest thing to do would be to convert it to a for loop.
Also in the initial population of your list try using the newer way
var divisible = Enumerable.Range(1, val).ToList();
then do
for(int 0 = 1; i < val; i++)
{
if(val % d == 0)
{
// do something
}
else
{
divisible.RemoveAt(i);
}
}
My problem is, that I need to now, what statements passed through a If statement. The code is as follows.
int[] Array = {value1,value2,value3}
foreach {int Value in Array)
{
if (Value < 4)
{
// Here i need to know what values passed through that were less that 4, like
// which one, value 1, value 2, and/or value 3
}
So is there a solution for a problem? I'm kind of new to programming.
My problem is that i do not need an else statement, i Need to know if value 1 or 2 or 3 passed through. Exactly which ones are less than 4. EDIT: fixed some mistakes, was in a rush, forgot to put the sign the other way. When they are less than 4, i need to now which values passed through. Ill prob repost tho. As i messed up. I really don't care for now which ones are greater, or the else statement, i skipped that part.
Edit2: I also came up with a solution, but i don't if its good. Should i run a loop when i store values in the if statement, making another if statement, to compare if the ones inside the if statement are the same on the outside, and then knowing which values passed through?
I'm not 100% positive if I understand the question but it seems you can use the else statement
if (Value > 4)
{
// Do your stuff for elements greater than 4
}
else
{
// Do your stuff for elements greater lower or equal than 4
}
How about use for instead of foreach, since you got index of array member, you will know which one passed through
int[] array = {value1, value2, value3}
for (int index = 0; index < array.Count(); index++)
{
if (array[index] < 4)
{
// do sth with index
}
}
int Array[] = {value1,value2,value3}
foreach {int Value in Array)
{
if (Value > 4)
{
// Here i need to know what elements passed through that were less that 4
}else if(Value < 4){
//values < 4 will execute this code
}
I'm going to make a few general suggestions that should hopefully be helpful. First of all, your conditional says if (Value > 4) so you will not go into that code block where you suggest figuring out which elements are less than 4. Instead you'd need an else. So here's one way;
int Array[] = {value1,value2,value3}
List<int> lessThanFour = new List<int>();
foreach {int Value in Array)
{
if (Value < 4)
{
lessThanFour.Add(Value);
Console.WriteLine(Value);
}
}
The above code puts each value which is less than four into a list so you can access them later. It also prints them to the console.
Another option would be to use LINQ;
var lessThanFour = Array.Where(x => x < 4);
foreach (int c in lessThanFor)
Console.WriteLine(c);
The above code uses the Where operator to create a new array with all ints in the original that have a value less than for. The statement x => x < 4 is best to think of in an iterative since where x is the current element. It works the same as the foreach loop. When you execute that code it basically says, for each int x in Array, if x is less than four add it to the result. Then I use a foreach below that to print out the results.
Your question is poorly framed I think but it sounds like you are looking for a switch case.
if (x < 4) {
switch (x) {
case 1:
Console.WriteLine("Case 1");
break;
case 2:
Console.WriteLine("Case 2");
break;
case 3:
Console.WriteLine("Case 3");
break;
default:
Console.WriteLine("Default case");
break;
}
}
I have custom class that implement IEnumerable<int[]> interface and save current Enumerator. When added new element I need set enumerator to last element.
Sample code for set enumerator to end:
IEnumerable<int> seq = ...
seq.Reset();
for (int i = 0; i < seq.Count; i++)
{
seq.MoveNext();
}
How do this faster?
(Can I go to the end can't not scroll all sequence elements?)
if faster means less code (another alternative is),
IEnumerable<int> seq = ...
while (seq.MoveNext())
{
var item = seq.Current;
}
EDIT
you want seq.Last()
It is an extension method and has code similar to above.
EDIT2
i need seq.Current=seq.Last();
your code is similar to
IEnumerable<int> seq = ...
int count=0;
//Following while is equivalent to seq.Count
while (seq.MoveNext())
{
count++;
}
int i=0;
while (i<count)
{
seq.MoveNext();
}
Using IEnumerator only it is not possible to set seq.Current to Last in one iteration as you never know where to stop.
The for statement will iterate from x to y, with a pre-defined increment, like so:
for (`start`; `until`; `increment`)
e.g. If we wanted to loop from 0 to 9, with an increment of 1, we would write
for (int i = 0; i < 10; i++)
If you have an object that implements a next type method, you may want to use a while loop.
while (seq.CurrentItem != null)
{
// do something with the current item and move to next
seq.Next();
}
I would recommend reading up about loops in C#.
I have this assignment where I must delete a chosen element from an array, so I came up with this code:
strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
if (strItems[i] == strInput)
{
strItems[i] = null;
for (int x = 0; x < intAmount-i; x++)
{
i = i + 1;
strItems[i - 1] = strItems[i];
}
intAmount = intAmount - 1;
}
}
The problem is that, suppose I have an array [1,2,3,4,5,], and I want to delete 1. The output would be [2,3,4,5,5]. This also happens when I choose 2, but it does not happen when I choose any other number.
What am I doing wrong?
I'm assuming you are working with a basic array of strings:
var strItems = new string[] { "1", "2", "3", "4", "5" };
In .NET, that array is always going to be 5 elements long. In order to remove an element, you are going to have to copy the remaining elements to a new array and return it. Setting the value at a position to null does not remove it from the array.
Now, with things like LINQ this is very easy (not shown here), or you could cheat using the List<> collection and do this:
var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();
But I don't think that's going to teach you anything.
The first step is to find the index of the element you wish to remove. You can use Array.IndexOf to help you out. Let's find the middle element, "3":
int removeIndex = Array.IndexOf(strItems, "3");
If the element was not found, it will return a -1, so check for that before doing anything.
if (removeIndex >= 0)
{
// continue...
}
Finally you have to copy the elements (except the one at the index we don't want) to a new array. So, altogether, you end up with something like this (commented for explanation):
string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };
int removeIndex = Array.IndexOf(strItems, strInput);
if (removeIndex >= 0)
{
// declare and define a new array one element shorter than the old array
string[] newStrItems = new string[strItems.Length - 1];
// loop from 0 to the length of the new array, with i being the position
// in the new array, and j being the position in the old array
for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
{
// if the index equals the one we want to remove, bump
// j up by one to "skip" the value in the original array
if (i == removeIndex)
{
j++;
}
// assign the good element from the original array to the
// new array at the appropriate position
newStrItems[i] = strItems[j];
}
// overwrite the old array with the new one
strItems = newStrItems;
}
And now strItems will be the new array, minus the value specified for removal.
Arrays in C# are of a fixed size - once initialized you can only modify items, but you cannot add or remove items. If you want to delete an item from a collection you have two options:
1.) Create a new array that has all members of the original array minus the one you want to remove.
2.) Use a collection type that is resizable and allows to add or remove items like List<T> (List<int> in your case). This is what you would do in the "real world" if your collection is not static.
In your specific implementation i think u miss a break; statement, you should go out from the outer loop when you finish the inner loop. The assignment to null is not useful at all.
If the list is just a list of numbers why are you using strings? use integers directly if it is the case.
Your exercise seems to ask something like this, if you need to remove only one element.
public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
bool found = false;
for (int i = 0; i < array.Length; ++i)
{
if (found)
{
array[i - 1] = array[i];
}
else if (array[i] == value)
{
found = true;
}
}
return found;
}
This function will returns true if it find the specified falue, false if not.
It will move all items as you describe in your example, but of course, it will not change the size of the array.
Arrays are fixed size.
You cannot change the size of an array, simply, the language don't allows that.
Arrays are, were and will be always fixed size!
To remove an item from an array you should do something this:
public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
int count = array.Length - 1;
T[] result = new T[count];
if (index > 0)
Array.Copy(array, 0, result, 0, index - 1);
if (index < size)
Array.Copy(array, index + 1, result, index, size - index);
return result;
}
...
strItems = RemoveAt(strItems, index);
This function will create a new array that contains all elements except the one at the index you specify.
Now, why someone would do something like this instead of using a List or a Dictionary or wathever?
Use directly a List without using an array.
Can use Except method to filter the data
AllData = {10, 30, 20, 50}
FilterData = {30, 20}
Result = AllData.Except(​FilterData)
Result will be {10, 50}
Arrays are a fixed sized, you can't shorten their length without creating a new array. All you can do is store the length of valid elements in the array (ie. after you remove 1 the length is 4).
Also, I'm not sure if the order of elements in your array is important, but if it's not you could swap the first and last elements rather than moving every element after the one that's removed forward 1 position.
An alternative to using an array is using a collection such as an ArrayList which will take care of resizing, removing and keeping a count of the amount of items in it, plus a lot more.
However, since this is homework you might have to use arrays. Either keep track of the length with a variable, as opposed to using array.length, or create a new array each time you want to change the size. If you don't have to use arrays then look at the collections you can use in C#.
My method has a parameter, I have to use that in my For loop to iterate.
For example, I have a text file with 4 lines.
If the Param is 1, the for loop must iterate through the last three lines
If the Param is 2, the for loop must iterate through the last two lines
If the Param is 3, the for loop must iterate through the last one line
How can i pass this param in my For loop to achieve all the three scenarios stated above ?
for(int i = param; i < lines.Count ; i++) {...}
or with LINQ:
foreach(var line in lines.Skip(lines.Count - param)) {...}
You should try something like
for (int i = param; i < whateverCount; i++)
{
// do something
}
Where param would be the item to start from. Just remember that MOST arrays/list are zero based, but there are cases where they are 1 based.
private void YourFunction(int value)
{
for(int x=0;x<4-value;x++)
{
//loop will happen 4 - value times, 4-3 = 1, 4-2 =2, 4-1 = 3 times
}
}