Nesting loop to get one of each - c#

I'm trying to make a look to print each of every value once:
Something like this.
Lets pretend that the object letters contains "one,two ...ten"
And then there is the object numbers that contains "1,2,3,4...10"
Now if I want the loop to print:
One
1
Two
2
Three
3
How would the loop look like?
I tried it like this:
foreach (var i in letters)
{
Console.WriteLine(i);
foreach(var a in numbers)
{
Console.WriteLine(a);
}
}
But this returns:
One
1
2
Two
1
2
Three
1
2
And that result isn't what I want..
How can I nest the loops to make it print the way I want it?

Maybe you can use IEnumerable<T>.Zip(...), see here, to make combinations.
var data = letters.Zip(numbers, (l, n) => new { letter = l, number = n})
foreach (var item in data) {
Console.Writeline(item.letter);
Console.Writeline(item.number);
}

use forloop insted of foreach use it like this
for (int i=0;i<letters.length;i++)
{
Console.WriteLine(letters[i]);
Console.WriteLine(numbers[i]);
}

Don't do two nested loops, they are for enumerating over all possible pairs from two collections.
Instead, make a loop on the index, and use it for both collections, or use LINQ's Zip method:
foreach (var pair in letters.Zip(numbers, (l, n) => new {Letter=l, Number=n})) {
Console.WriteLine("{0} - {1}", pair.Letter, pair.Number);
}

Assuming your Numbers and Letters are collections that derive from IEnumerable, you could do something like this:
var zipped = letters.Zip(numbers, Tuple.Create);
foreach (var tuple in zipped)
{
Console.WriteLine(tuple.Item1);
Console.WriteLine(tuple.Item2);
}

You need a single loop to iterate over both lists:
for (int index = 0; index < letters.Count; index++)
{
Console.WriteLine(letters[index]);
Console.WriteLine(numbers[index]);
}
This presupposes that your lists are the same length. If they're not you'd have to set the upper limit to the length of the shorter list.
for (int index = 0; index < Math.Min(letters.Count, numbers.Count); index++)

You're close - the second loop should not be within the first, but you should use one loop to iterate over both arrays. Try:
for (int i = 0; i < letters.size(); i++) {
Console.WriteLine(letters.getItem(i));
Console.WriteLine(numbers.getItem(i));
}
Note that this assumes a size() method to return the number of items and a getItem() method to return a specific item from the object.

What's happening is that for every time your outside loop runs, the inside one runs twice.
That's because your loops are nested, there's no getting around this.
If you absolutely must use nested loops for this, you'd have to add a check whether your number has been printed yet
Something like:
foreach(var i in letters)
{
Console.WriteLine(i);
foreach(var a in numbers)
{
if (a.isPrinted) //if it has been printed already
{
continue; //skip ahead
}
else
{
Console.WriteLine(a.number);
a.isPrinted = true;
break; //stop and jump out of the foreach loop
}
}
}
This also means that each number is actually an object that holds the bool isPrinted and int number
I wouldn't doing it like that, it's ridiculously inefficient.
You should do what others have already suggested.

Related

How to iterate a `foreach loop` between index 40-60?

I have a simple question that I can't find a clean answer to when I google.
How do I iterate a foreach loop between index 40-60 and get the values for the indexes?
List<int> list1 = new List<int>();
for (int i = 0; i < 100; i++)
{
list1.Add(i);
}
foreach (var i in list1)
{
//How to iterate between index: 40 to 60 ?
}
The easiest approach would be to use a regular for loop:
for (int i = 40; i < 60; ++i)
{
int value = list1[i];
// Do something with the value
}
Note - if you want to get the value for index 60 too (i.e., the range is inclusive), you should use the <= operator instead of <.
Foreach loop doesn't use an index for traversing an array or collection. They take advantage of the enumerator in an IEnumerable. This answer here has a great explanation of that.
If you want you can add an int before the foreach loop and increment within the loop, but that's all you can do. I would advise that you filter your list1 beforehand and then use it in the foreach loop.
If you really want to use a foreach then you need to write this
List<int> list1 = new List<int>();
foreach(int i in Enumerable.Range(40, 20))
{
list1.Add(i);
}
But, lacking better info on your request to use foreach, then I agree to use a standard for-loop
Aside from other more appropriate answers (e.g. just use a for loop), here's a solution that uses the .Where() overload that provides the index of the element as a parameter to the predicate:
foreach (var i in list1.Where((x, index) => index >= 40 && index <= 60))
{
//How to iterate between index: 40 to 60 ?
}

Turning a for(;;) loop into a foreach

So I've been trying to turn this codes for into a for each, but I keep running into problems, and I'm not all that sure how to do it, the only thing I've done that will work is a small code but it repeats several times, I'm still really new to C# and using for() so I'm not really understanding what to do. Sorry for being so new to this, and I appreciate all the help I can get!
double[] numbers = new double[9.7, 2.2, 4.3, 1.7, 5.6, 3.6, 4.5, 1.3, 4.6, 3.0];
static double ComputeSum(double[] array)
{
double sum = 0;
int intCounter;
for (intCounter = 0; intCounter < array.Length; intCounter++)
{
sum += array[intCounter];
}
return sum;
}
static double ComputeAverage(double[] array)
{
return ComputeSum(array) / array.Length;
}
You got your specific question answered, but not the more general question of "how do I turn a for loop into a foreach?
Let's look at your loop, with some better naming. (Don't name things according to their type in C#. Name things according to their meaning.)
for (index = 0; index< array.Length; index++)
{
sum += array[index];
}
The most important thing is that you understand the idea that this loop represents. A surface level reading is "for every valid index in this array, obtain the element value associated with that index and add it to the sum". But we can make that a bit more abstract. We could also say that the loop means "for every element in the collection, add it to the sum".
That is the key difference between the for loop and the foreach loop. The for loop concentrates on the index, and you fetch the value via the index. The foreach loop concentrates on the value itself, and doesn't consider the index at all.
Knowing that we can now see how to translate a for into a foreach. First locate the bit that is the value, and make a variable for it:
for (index = 0; index < array.Length; index++)
{
var item = array[index];
sum += item;
}
Now we see that the loop body can be expressed almost entirely in terms of an operation on the item, not on the index. We then translate that into a foreach:
foreach (var item in array)
{
sum += item;
}
Everything dealing with the index gets deleted. If you find you cannot delete everything dealing with the index, then you probably should not be using a foreach.
Since foreach loop presents elements of the collection one-by-one to your code, all you need to do is
foreach (double num in Numbers)
{
sump += num;
}
Console.WriteLine("{0}", sump);
You could also use Sum extension method to eliminate loop constructs altogether:
var sump = Numbers.Sum(); // <<== The loop is hidden inside the Sum() method
Console.WriteLine("{0}", sump);

What is the difference between for and foreach?

What is the major difference between for and foreach loops?
In which scenarios can we use for and not foreach and vice versa.
Would it be possible to show with a simple program?
Both seem the same to me. I can't differentiate them.
a for loop is a construct that says "perform this operation n. times".
a foreach loop is a construct that says "perform this operation against each value/object in this IEnumerable"
You can use foreach if the object you want to iterate over implements the IEnumerable interface. You need to use for if you can access the object only by index.
I'll tryto answer this in a more general approach:
foreach is used to iterate over each element of a given set or list (anything implementing IEnumerable) in a predefined manner. You can't influence the exact order (other than skipping entries or canceling the whole loop), as that's determined by the container.
foreach (String line in document) { // iterate through all elements of "document" as String objects
Console.Write(line); // print the line
}
for is just another way to write a loop that has code executed before entering the loop and once after every iteration. It's usually used to loop through code a given number of times. Contrary to foreach here you're able to influence the current position.
for (int i = 0, j = 0; i < 100 && j < 10; ++i) { // set i and j to 0, then loop as long as i is less than 100 or j is less than 10 and increase i after each iteration
if (i % 8 == 0) { // skip all numbers that can be divided by 8 and count them in j
++j
continue;
}
Console.Write(i);
}
Console.Write(j);
If possible and applicable, always use foreach rather than for (assuming there's some array index). Depending on internal data organisation, foreach can be a lot faster than using for with an index (esp. when using linked lists).
Everybody gave you the right answer with regard to foreach, i.e. it's a way to loop through the elements of something implementing IEnumerable.
On the other side, for is much more flexible than what is shown in the other answers. In fact, for is used to executes a block of statements for as long as a specified condition is true.
From Microsoft documentation:
for (initialization; test; increment)
statement
initialization
Required. An expression. This expression is executed only once, before the loop is executed.
test
Required. A Boolean expression. If test is true, statement is executed. If test if false, the loop is terminated.
increment
Required. An expression. The increment expression is executed at the end of every pass through the loop.
statement
Optional. Statement to be executed if test is true. Can be a compound statement.
This means that you can use it in many different ways. Classic school examples are the sum of the numbers from 1 to 10:
int sum = 0;
for (int i = 0; i <= 10; i++)
sum = sum + i;
But you can use it to sum the numbers in an Array, too:
int[] anArr = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 };
int sum = 0;
for (int i = 0; i < anArr.Length; i++)
sum = sum + anArr[i];
(this could have been done with a foreach, too):
int[] anArr = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 };
int sum = 0;
foreach (int anInt in anArr)
sum = sum + anInt;
But you can use it for the sum of the even numbers from 1 to 10:
int sum = 0;
for (int i = 0; i <= 10; i = i + 2)
sum = sum + i;
And you can even invent some crazy thing like this one:
int i = 65;
for (string s = string.Empty; s != "ABC"; s = s + Convert.ToChar(i++).ToString()) ;
Console.WriteLine(s);
for loop:
1) need to specify the loop bounds( minimum or maximum).
2) executes a statement or a block of statements repeatedly
until a specified expression evaluates to false.
Ex1:-
int K = 0;
for (int x = 1; x <= 9; x++){
k = k + x ;
}
foreach statement:
1)do not need to specify the loop bounds minimum or maximum.
2)repeats a group of embedded statements for
a)each element in an array
or b) an object collection.
Ex2:-
int k = 0;
int[] tempArr = new int[] { 0, 2, 3, 8, 17 };
foreach (int i in tempArr){
k = k + i ;
}
foreach is almost equivalent to :
var enumerator = list.GetEnumerator();
var element;
while(enumerator.MoveNext()){
element = enumerator.Current;
}
and in order to implemetn a "foreach" compliant pattern, this need to provide a class that have a method GetEnumerator() which returns an object that have a MoveNext() method, a Reset() method and a Current property.
Indeed, you do not need to implement neither IEnumerable nor IEnumerator.
Some derived points:
foreach does not need to know the collection length so allows to iterate through a "stream" or a kind of "elements producer".
foreach calls virtual methods on the iterator (the most of the time) so can perform less well than for.
It depends on what you are doing, and what you need.
If you are iterating through a collection of items, and do not care about the index values then foreach is more convenient, easier to write and safer: you can't get the number of items wrong.
If you need to process every second item in a collection for example, or process them ion the reverse order, then a for loop is the only practical way.
The biggest differences are that a foreach loop processes an instance of each element in a collection in turn, while a for loop can work with any data and is not restricted to collection elements alone. This means that a for loop can modify a collection - which is illegal and will cause an error in a foreach loop.
For more detail, see MSDN : foreach and for
Difference Between For and For Each Loop in C#
For Loops executes a block of code until an expression returns false while ForEach loop executed a block of code through the items in object collections.
For loop can execute with object collections or without any object collections while ForEach loop can execute with object collections only.
The for loop is a normal loop construct which can be used for multiple purposes where as foreach is designed to work only on Collections or IEnumerables object.
foreach is useful if you have a array or other IEnumerable Collection of data. but for can be used for access elements of an array that can be accessed by their index.
A for loop is useful when you have an indication or determination, in advance, of how many times you want a loop to run. As an example, if you need to perform a process for each day of the week, you know you want 7 loops.
A foreach loop is when you want to repeat a process for all pieces of a collection or array, but it is not important specifically how many times the loop runs. As an example, you are formatting a list of favorite books for users. Every user may have a different number of books, or none, and we don't really care how many it is, we just want the loop to act on all of them.
The for loop executes a statement or a block of statements repeatedly until a specified expression evaluates to false.
There is a need to specify the loop bounds (minimum or maximum). Following is a code example of a simple for loop that starts 0 till <= 5.
we look at foreach in detail. What looks like a simple loop on the outside is actually a complex data structure called an enumerator:
An enumerator is a data structure with a Current property, a MoveNext method, and a Reset method. The Current property holds the value of the current element, and every call to MoveNext advances the enumerator to the next item in the sequence.
Enumerators are great because they can handle any iterative data structure. In fact, they are so powerful that all of LINQ is built on top of enumerators.
But the disadvantage of enumerators is that they require calls to Current and MoveNext for every element in the sequence. All those method calls add up, especially in mission-critical code.
Conversely, the for-loop only has to call get_Item for every element in the list. That’s one method call less than the foreach-loop, and the difference really shows.
So when should you use a foreach-loop, and when should you use a for-loop?
Here’s what you need to do:
When you’re using LINQ, use foreach
When you’re working with very large computed sequences of values, use foreach
When performance isn’t an issue, use foreach
But if you want top performance, use a for-loop instead
The major difference between the for and foreach loop in c# we understand by its working:
The for loop:
The for loop's variable always be integer only.
The For Loop executes the statement or block of statements repeatedly until specified expression evaluates to false.
In for loop we have to specify the loop's boundary ( maximum or minimum).-------->We can say this is the limitation of the for loop.
The foreach loop:
In the case of the foreach loop the variable of the loop while be same as the type of values under the array.
The Foreach statement repeats a group of embedded statements for each element in an array or an object collection.
In foreach loop, You do not need to specify the loop bounds minimum or maximum.--->
here we can say that this is the advantage of the for each loop.
I prefer the FOR loop in terms of performance. FOREACH is a little slow when you go with more number of items.
If you perform more business logic with the instance then FOREACH performs faster.
Demonstration:
I created a list of 10000000 instances and looping with FOR and FOREACH.
Time took to loop:
FOREACH -> 53.852ms
FOR -> 28.9232ms
Below is the sample code.
class Program
{
static void Main(string[] args)
{
List<TestClass> lst = new List<TestClass>();
for (int i = 1; i <= 10000000; i++)
{
TestClass obj = new TestClass() {
ID = i,
Name = "Name" + i.ToString()
};
lst.Add(obj);
}
DateTime start = DateTime.Now;
foreach (var obj in lst)
{
//obj.ID = obj.ID + 1;
//obj.Name = obj.Name + "1";
}
DateTime end = DateTime.Now;
var first = end.Subtract(start).TotalMilliseconds;
start = DateTime.Now;
for (int j = 0; j<lst.Count;j++)
{
//lst[j].ID = lst[j].ID + 1;
//lst[j].Name = lst[j].Name + "1";
}
end = DateTime.Now;
var second = end.Subtract(start).TotalMilliseconds;
}
}
public class TestClass
{
public long ID { get; set; }
public string Name { get; set; }
}
If I uncomment the code inside the loop:
Then, time took to loop:
FOREACH -> 2564.1405ms
FOR -> 2753.0017ms
Conclusion
If you do more business logic with the instance, then FOREACH is recommended.
If you are not doing much logic with the instance, then FOR is recommended.
Many answers are already there, I just need to identify one difference which is not there.
for loop is fail-safe while foreach loop is fail-fast.
Fail-fast iteration throws ConcurrentModificationException if iteration and modification are done at the same time in object.
However, fail-safe iteration keeps the operation safe from failing even if the iteration goes in infinite loop.
public class ConcurrentModification {
public static void main(String[] args) {
List<String> str = new ArrayList<>();
for(int i=0; i<1000; i++){
str.add(String.valueOf(i));
}
/**
* this for loop is fail-safe. It goes into infinite loop but does not fail.
*/
for(int i=0; i<str.size(); i++){
System.out.println(str.get(i));
str.add(i+ " " + "10");
}
/**
* throws ConcurrentModificationexception
for(String st: str){
System.out.println(st);
str.add("10");
}
*/
/* throws ConcurrentModificationException
Iterator<String> itr = str.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
str.add("10");
}*/
}
}
Hope this helps to understand the difference between for and foreach loop through different angle.
I found a good blog to go through the differences between fail-safe and fail-fast, if anyone interested:
You can use the foreach for an simple array like
int[] test = { 0, 1, 2, 3, ...};
And you can use the for when you have a 2D array
int[][] test = {{1,2,3,4},
{5,2,6,5,8}};
foreach syntax is quick and easy. for syntax is a little more complex, but is also more flexible.
foreach is useful when iterating all of the items in a collection. for is useful when iterating overall or a subset of items.
The foreach iteration variable which provides each collection item, is READ-ONLY, so we can't modify the items as they are iterated. Using the for syntax, we can modify the items as needed.
Bottom line- use foreach to quickly iterate all of the items in a collection. Use for to iterate a subset of the items of the collection or to modify the items as they are iterated.
simple difference between for and foreach
for loop is working with values. it must have condition then increment and intialization also. you have to knowledge about 'how many times loop repeated'.
foreach is working with objects and enumaretors. no need to knowledge how many times loop repeated.
The foreach statement repeats a group of embedded statements for each element in an array or an object collection that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable interface. The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.
One important thing related with foreach is that , foreach iteration variable cannot be updated(or assign new value) in loop body.
for example :
List<string> myStrlist = new List<string>() { "Sachin", "Ganguly", "Dravid" };
foreach(string item in myStrlist)
{
item += " cricket"; // ***Not Possible***
}

Remove list elements at given indices

I have a list which contains some items of type string.
List<string> lstOriginal;
I have another list which contains idices which should be removed from first list.
List<int> lstIndices;
I'd tried to do the job with RemoveAt() method ,
foreach(int indice in lstIndices)
{
lstOriginal.RemoveAt(indice);
}
but it crashes and said me that "index is Out of Range."
You need to sort the indexes that you would like to return from largest to smallest in order to avoid removing something at the wrong index.
foreach(int indice in lstIndices.OrderByDescending(v => v))
{
lstOriginal.RemoveAt(indice);
}
Here is why: let's say have a list of five items, and you'd like to remove items at indexes 2 and 4. If you remove the item at 2 first, the item that was at index 4 would be at index 3, and index 4 would no longer be in the list at all (causing your exception). If you go backwards, all indexes would be there up to the moment when you're ready to remove the corresponding item.
How are you populating the list of indices? There's a much more efficient RemoveAll method that you might be able to use. For example, instead of this:
var indices = new List<int>();
int index = 0;
foreach (var item in data)
if (SomeFunction(data))
indices.Add(index++);
//then some logic to remove the items
you could do this:
data.RemoveAll(item => SomeFunction(item));
This minimizes the copying of items to new positions in the array; each item is copied only once.
You could also use a method group conversion in the above example, instead of a lambda:
data.RemoveAll(SomeFunction);
The reason this is happening is because when you remove an item from the list, the index of each item after it effectively decreases by one, so if you remove them in increasing index order and some items near the end of the original list were to be removed, those indices are now invalid because the list becomes shorter as the earlier items are removed.
The easiest solution is to sort your index list in decreasing order (highest index first) and then iterate across that.
for (int i = 0; i < indices.Count; i++)
{
items.RemoveAt(indices[i] - i);
}
My in-place deleting of given indices as handy extension method. It copies all items only once so it is much more performant if large amount of indicies is to be removed.
It also throws ArgumentOutOfRangeException in case where index to remove is out of bounds.
public static class ListExtensions
{
public static void RemoveAllIndices<T>(this List<T> list, IEnumerable<int> indices)
{
//do not remove Distinct() call here, it's important
var indicesOrdered = indices.Distinct().ToArray();
if(indicesOrdered.Length == 0)
return;
Array.Sort(indicesOrdered);
if (indicesOrdered[0] < 0 || indicesOrdered[indicesOrdered.Length - 1] >= list.Count)
throw new ArgumentOutOfRangeException();
int indexToRemove = 0;
int newIdx = 0;
for (int originalIdx = 0; originalIdx < list.Count; originalIdx++)
{
if(indexToRemove < indicesOrdered.Length && indicesOrdered[indexToRemove] == originalIdx)
{
indexToRemove++;
}
else
{
list[newIdx++] = list[originalIdx];
}
}
list.RemoveRange(newIdx, list.Count - newIdx);
}
}
var array = lstOriginal.ConvertAll(item => new int?(item)).ToArray();
lstIndices.ForEach(index => array[index] = null);
lstOriginal = array.Where(item => item.HasValue).Select(item => item.Value).ToList();
lstIndices.OrderByDescending(p => p).ToList().ForEach(p => lstOriginal.RemoveAt((int)p));
As a side note, in foreach statements, it is better not to modify the Ienumerable on which foreach is running. The out of range error is probably as a result of this situation.

Exception on list.remove() even numbers

I have a list of numbers and I’d like to remove all the even ones. I think my code is right:
System.Collections.Generic.List<int> list = ...
foreach (int i in list)
{
if (i % 2 == 0)
list.Remove(i);
}
but when I run it I get an exception. What am I doing wrong?
You can't modify a collection in a foreach loop, that being said,
you can't remove an item from a list that you're iterating over in a foreach loop.
Instead of the foreach loop, just use this single line of code:
list.RemoveAll(i => i % 2 == 0);
You cannot modify the collection during a foreach loop. A foreach loop uses an enumerator to loop through the collection, and when the collection is modified this is what happens to the enumerator:
An enumerator remains valid as long as the collection remains
unchanged. If changes are made to the collection, such as adding,
modifying, or deleting elements, the enumerator is irrecoverably
invalidated and its behavior is undefined.
You can use a regular for loop.
for (int i = 0; i < list.Count; i++)
{
int n = list[i];
if (n % 2 == 0)
{
list.RemoveAt(i--);
}
}
The foreach uses an IEnumerator under the covers, when an element in your list is removed, it leaves the enumerator in a potentially inconsistent state. The 'safest' thing for it to do is throw an exception.
To work around this, make a local copy of your collection first:
var local = new List<int>(list);
foreach (int i in local) { if (i % 2 == 0) list.Remove(i); }
If you're removing from a list of anything (or even an array) you should iterate backward through it as removing an item shifts all items after it down by one position. Iterating forward will cause you to skip over the next item each time.
Which exception did you get? Sometimes foreach will lock an item to where it can't be edited when it's used in the foreach. Instead, use for (and go backwards!)
for(int i = list.Length - 1 ; i > -1 ; i--)
to follow #Chris Filstow's method....
this will take your list, and replace it with a new one where the elements meet your criteria:
System.Collections.Generic.List<int> list = ...
list = list.Where( n=> n % 2 == 0 ).ToList();
You could try something like this instead. (It creates a new list of just the even numbers rather than removing the odds from the existing list, so it depends on what you're looking to do.)
var numbers = Enumerable.Range(1, 100);
var evens = numbers.Where(n => n % 2 == 1);
All your getting out of the foreach loop is readonly if you try to change the items in the list it explains why you get an exception.
This article right here explains why.
You could alway switch to a for loop.
for (int i = 1 ; i < list.lenght; i++)
{
if (i % 2 == 0)
list.Remove(i);
}

Categories

Resources