C# reference to loop variable - c#

Is it possible in C# to something like the following
foreach (ref string var in arr) {
var = "new value";
}
so that var variable was treated as reference and assigning to var would change an array element?

There is no such construct for updating a loop; an iterator is read-only. For example, the following provides a perfectly valid iterator:
public IEnumerable<int> Get1Thru5() {
yield return 1; yield return 2; yield return 3;
yield return 4; yield return 5;
}
How would it update? What would it update?
If the data is an array/list/etc, then something like:
for(int i = 0 ; i < arr.Length ; i++) {
arr[i] = "new value";
}
Or other options depending on the specific container.
Update; at a push, an extension method:
public static void UpdateAll<T>(this IList<T> list, Func<T, T> operation) {
for (int i = 0; i < list.Count; i++) {
list[i] = operation(list[i]);
}
}
static void Main() {
string[] arr = { "abc", "def", "ghi" };
arr.UpdateAll(s => "new value");
foreach (string s in arr) Console.WriteLine(s);
}

No. The foreach statement is simply syntax sugar on top of the IEnumerable interface. This interface defines a method to get en IEnumerator which in turn has methods to do read-only enumeration:
Current : object
MoveNext() : bool
Reset() : void

foreach(string s in strings)
{
Console.WriteLine(s);
}
is compiler shortcut for:
IEnumerator e = strings.GetEnumerator();
string s;
while(e.MoveNext())
{
s = e.Current;
Console.WriteLine(s);
}
Since IEnumerator.Current is a get-only property you can't set the value.
// Non-generic IEnumerator shown.
interface IEnumerator
{
bool MoveNext();
object Current { get; }
void Reset();
}
If you want to support an updatable enumerator you will need to create it yourself -- but you won't be able to use "foreach" with it, and you'll have to implement wrappers around all the common IEnumerable classes.
You'll have to analyze your current situation and figure out how to update. If you're using an IList interface you can do:
for(int i = 0; i < strings.Count; ++i)
{
string s = strings[i];
//do work
s = s.ToUpperInvariant();
strings[i] = s;
}

In the case of a string, no; C#
strings are immutable (cannot be
changed). If you were enumerating over
objects of a different, mutable type,
you can change the properties of those
objects.
Just to illustrate what Jacob is talking about. Consider the code snippet below:
class MyInt
{
public int Val { get; set; }
public MyInt(int val) { this.Val = val; }
}
class Program
{
static void Main(string[] args)
{
MyInt[] array = new MyInt[] { new MyInt(1), new MyInt(2) };
foreach (var obj in array) Console.Write("{0}\t", obj.Val);
foreach (var obj in array)
{
obj = new MyInt(100); // This doesn't compile! the reference is read only
obj.Val *= 10; // This works just fine!
}
foreach (var obj in array) Console.Write("{0}\t", obj.Val);
}
}
Indeed, if you try to assign to the "obj" as above you'll get a compile time error. But nothing prevents you from modifying MyInt's properties through the "obj" reference

In the case of a string, no; C# strings are immutable (cannot be changed). If you were enumerating over objects of a different, mutable type, you can change the properties of those objects.

Related

What is the java Vector.element() C# equivalent

Here is the java code i incompletely tried to translate
static Enumeration enumerate()
{
Vector list = new Vector();
Enumeration e = cache.keys();
while (e.hasMoreElements())
{
Vector v = (Vector) cache.get(e.nextElement());
for (int i = 0; i < v.size(); i++)
{
list.addElement(v.elementAt(i));
}
}
return list.elements();
}
This is the C# translation but not complete
public static IEnumerable<Http> enumurate()
{
List<Http> list = new List<Http>();
IEnumerator e = cache.Keys.GetEnumerator();
while (e.MoveNext())/*While e has more element*/
{
var vector = (List<Http>)cache[e.Current];
for (int i = 0; i < vector.Count; i++)
{
list.Add(vector.ElementAt<Http>(i));
}
}
return //Something missing!!
}
Any help please !
In C# List<Http> implements IEnumerable<Http> so you can simply return your list:
return list;
To convert the code to C# even more, you could just skip the adding of elements to the list and yield results directly:
public static IEnumerable<Http> enumerate()
{
IEnumerator e = cache.Keys.GetEnumerator();
while (e.MoveNext())/*While e has more element*/
{
var vector = (List<Http>)cache[e.Current];
for (int i = 0; i < vector.Count; i++)
{
yield return vector.ElementAt<Http>(i);
}
}
}
Also, you can avoid using enumerators directly and make the code even more readable:
public static IEnumerable<Http> enumerate()
{
foreach (var key in cache.Keys)
{
foreach (var http in (List<Http>)cache[key])
{
yield return http;
}
}
}
Just return the local list. List<T> implements IEnumerable<T>.
In C# you can use LINQ to simplify your code:
public static IEnumerable<Http> enumerate()
{ return cache.Keys.SelectMany(key => (List<Http>)cache[key]); }
Assuming cache is declared as Dictionary<..., List<Http>> you can avoid key lookup by using the Values property:
public static IEnumerable<Http> enumerate()
{ return cache.Values.SelectMany(list => list); }
One important difference between the above and the code that you have now is that the above is not evaluated until you actually try to iterate through the returned collection. If you want to evaluate results immediately, you can add a call to .ToList(). This is equivalent to your original code:
public static IEnumerable<Http> enumerate()
{ return cache.Keys.SelectMany(key => (List<Http>)cache[key]).ToList(); }

How to create dynamic incrementing variable using “for” loop in C#

How to create dynamic incrementing variable using "for" loop in C#? like this:
track_1, track_2, track_3, track_4. so on.
You can't create dynamically-named variables. All you can do - it to create some collection or array, and operate with it.
I think the best class for you is generic List<>:
List<String> listWithDynamic = new List<String>();
for (int i = 1; i < limit; i +=1)
{
listWithDynamic.Add(string.Format("track_{0}", i));
...
}
Assuming you want strings:
for (int i = 1; i < limit; i +=1)
{
string track = string.Format("track_{0}", i);
...
}
But when you already have variables called track_1, track_2, track_3, track_4 you will need an array or List:
var tracks = new TrackType[] { track_1, track_2, track_3, track_4 } ;
for (int i = 0; i < tracks.length; i++)
{
var track = tracks[i]; // tracks[0] == track_1
...
}
Obvious Solution
for (var i = 0; i < 10; i++)
{
var track = string.Format("track_{0}", i);
}
Linq-Based Solution
foreach (var track in Enumerable.Range(0, 100).Select(x => string.Format("track_{0}", x)))
{
}
Operator-Based Solution This is somewhat hacky, but fun none-the-less.
for (var i = new Frob(0, "track_{0}"); i < 100; i++)
{
Console.WriteLine(i.ValueDescription);
}
struct Frob
{
public int Value { get; private set; }
public string ValueDescription { get; private set; }
private string _format;
public Frob(int value, string format)
: this()
{
Value = value;
ValueDescription = string.Format(format, value);
_format = format;
}
public static Frob operator ++(Frob value)
{
return new Frob(value.Value + 1, value._format);
}
public static Frob operator --(Frob value)
{
return new Frob(value.Value - 1, value._format);
}
public static implicit operator int(Frob value)
{
return value.Value;
}
public static implicit operator string(Frob value)
{
return value.ValueDescription;
}
public override bool Equals(object obj)
{
if (obj is Frob)
{
return ((Frob)obj).Value == Value;
}
else if (obj is string)
{
return ((string)obj) == ValueDescription;
}
else if (obj is int)
{
return ((int)obj) == Value;
}
else
{
return base.Equals(obj);
}
}
public override int GetHashCode()
{
return Value;
}
public override string ToString()
{
return ValueDescription;
}
}
don't know if I get your question, but I will try:
for(var i = 1; i < yourExclusiveUpperbound; i++)
{
var track = String.Format("$track_{0}", i);
// use track
}
or with some LINQ-Magic:
foreach(var track in Enumerate.Range(1, count)
.Select(i => String.Format("$track_{0}", i)))
{
// use track
}
Do as follow:
for (int i = 0; i < lenght; i ++)
{
any work do in loop
}
No, we can't create dynamically named variables in a loop. But, there are other elegant ways to address the problem instead of creating dynamically named variables.
One could be, create an array or list before the loop and store values in array / list items in the loop. You can access the array / list later anywhere in your code. If you know which variable you want to use (track_1, track_2, ...), you can simply access it from the array / list (tracks[1], tracks[2], ...).
List<String> tracks = new List<String>();
for (int i = 1; i < limit; i++)
{
Track track = new Track();
tracks.Add(track);
...
}

Changing Foreach Order?

Is there anyway to foreach through a list from the end to the beginning rather than the beginning to then end (preferably without reordering the list).
using System.Linq;
foreach(var item in source.Reverse())
{
...
}
Edit: There is one more step if you are dealing specifically with a List<T>. That class defines its own Reverse method whose signature is not the same as the Enumerable.Reverse extension method. In that case, you need to "lift" the variable reference to IEnumerable<T>:
using System.Linq;
foreach(var item in list.AsEnumerable().Reverse())
{
...
}
you could use a regular for loop, start at the end and decrement, instead of starting at the top and incrementing.
something like:
for(int i=foo.lenth; i != 0; i--)
{
do stuff
}
You probably don't want to do anything complicated, so I would suggest just using a for loop.
However, if it were somehow a requirement, you can certainly implement your own iterators for custom list iteration behavior.
It depends on what you mean by list.
List<T> ? No, unless you use Linq and it's Reverse() function.
Your custom collection? Easily, just implement IEnumerator like you
want.
Error checking ommitted for clarity. Use a custom implementation of IEnumerable and IEnumerator. This will avoid unnecessary copying.
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class ReversedEnumerator : IEnumerator<int>
{
List<int> v;
int index;
public ReversedEnumerator(List<int> v) {
this.v = v;
this.index = v.Count;
}
public int Current
{
get { return v[index]; }
}
public void Dispose()
{
}
object System.Collections.IEnumerator.Current
{
get { return v[index]; }
}
public bool MoveNext()
{
return --index >= 0;
}
public void Reset()
{
index = this.v.Count;
}
}
class EnumeratorStub : IEnumerable<int>
{
List<int> v;
public EnumeratorStub(List<int> v)
{
this.v = v;
}
public IEnumerator<int> GetEnumerator()
{
return new ReversedEnumerator(v);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return new ReversedEnumerator(v);
}
}
class Program
{
static EnumeratorStub Reverse(List<int> v)
{
return new EnumeratorStub(v);
}
static void Main(string[] args)
{
List<int> v = new List<int>();
v.Add(1);
v.Add(2);
v.Add(3);
foreach (int item in Reverse(v))
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
I would recommend to refactor the code sample to use generics. That way you could use this for any container type.
IList<String> strList = new IList<String>();
strList.Add("A");
strList.Add("B");
strList.Add("C");
for (int i = strList.Count-1; i>=0;i--)
{
Console.WriteLine(strList[i]);
}
not tried but should work.
not c# but you can do it too :-)
Dim a As New List(Of Integer)
a.Add(1)
a.Add(2)
a.Add(3)
For Each i In a.AsEnumerable.Reverse
Debug.Print(i)
Next
You can construct your list as a stack and then iterate over the stack:
Stack<char> stack = new Stack<char>();
//Add items...
foreach(var item in stack)
{
...
}

How do I get around this lambda expression outer variable issue?

I'm playing with PropertyDescriptor and ICustomTypeDescriptor (still) trying to bind a WPF DataGrid to an object, for which the data is stored in a Dictionary.
Since if you pass WPF DataGrid a list of Dictionary objects it will auto generate columns based on the public properties of a dictionary (Comparer, Count, Keys and Values) my Person subclasses Dictionary and implements ICustomTypeDescriptor.
ICustomTypeDescriptor defines a GetProperties method which returns a PropertyDescriptorCollection.
PropertyDescriptor is abstract so you have to subclass it, I figured I'd have a constructor that took Func and an Action parameters that delegate the getting and setting of the values in the dictionary.
I then create a PersonPropertyDescriptor for each Key in the dictionary like this:
foreach (string s in this.Keys)
{
var descriptor = new PersonPropertyDescriptor(
s,
new Func<object>(() => { return this[s]; }),
new Action<object>(o => { this[s] = o; }));
propList.Add(descriptor);
}
The problem is that each property get's its own Func and Action but they all share the outer variable s so although the DataGrid autogenerates columns for "ID","FirstName","LastName", "Age", "Gender" they all get and set against "Gender" which is the final resting value of s in the foreach loop.
How can I ensure that each delegate uses the desired dictionary Key, i.e. the value of s at the time the Func/Action is instantiated?
Much obliged.
Here's the rest of my idea, I'm just experimenting here these are not 'real' classes...
// DataGrid binds to a People instance
public class People : List<Person>
{
public People()
{
this.Add(new Person());
}
}
public class Person : Dictionary<string, object>, ICustomTypeDescriptor
{
private static PropertyDescriptorCollection descriptors;
public Person()
{
this["ID"] = "201203";
this["FirstName"] = "Bud";
this["LastName"] = "Tree";
this["Age"] = 99;
this["Gender"] = "M";
}
//... other ICustomTypeDescriptor members...
public PropertyDescriptorCollection GetProperties()
{
if (descriptors == null)
{
var propList = new List<PropertyDescriptor>();
foreach (string s in this.Keys)
{
var descriptor = new PersonPropertyDescriptor(
s,
new Func<object>(() => { return this[s]; }),
new Action<object>(o => { this[s] = o; }));
propList.Add(descriptor);
}
descriptors = new PropertyDescriptorCollection(propList.ToArray());
}
return descriptors;
}
//... other other ICustomTypeDescriptor members...
}
public class PersonPropertyDescriptor : PropertyDescriptor
{
private Func<object> getFunc;
private Action<object> setAction;
public PersonPropertyDescriptor(string name, Func<object> getFunc, Action<object> setAction)
: base(name, null)
{
this.getFunc = getFunc;
this.setAction = setAction;
}
// other ... PropertyDescriptor members...
public override object GetValue(object component)
{
return getFunc();
}
public override void SetValue(object component, object value)
{
setAction(value);
}
}
Simply:
foreach (string s in this.Keys)
{
string copy = s;
var descriptor = new PersonPropertyDescriptor(
copy,
new Func<object>(() => { return this[copy]; }),
new Action<object>(o => { this[copy] = o; }));
propList.Add(descriptor);
}
With captured variables, it is where it is declared that is important. So by declaring the captured variable inside the loop, you get a different instance of the capture-class per iteration (the loop variable, s, is technically declared outside the loop).
Marc's solution is of course correct, but I thought I'd expand upon WHY below. As most of us know, if you declare a variable in a for or foreach statement, it only lives as long as what's inside, which makes it seem like the variable is the same as a variable declared in the statement-block of such a statement, but that's not right.
To understand it better, take the following for-loop. Then I'll re-state the "equivalent" loop in a while-form.
for(int i = 0; i < list.Length; i++)
{
string val;
list[i] = list[i]++;
val = list[i].ToString();
Console.WriteLine(val);
}
This works out to in while-form like below: (it isn't exactly the same, because continue will act differently, but for scoping rules, it's the same)
{
int i = 0;
while(i < list.Length)
{
{
string val;
list[i] = list[i]++;
val = list[i].ToString();
Console.WriteLine(val);
}
i++;
}
}
When "exploded" out this way, the scope of the variables becomes clearer, and you can see why it always captures the same "s" value in your program, and why Marc's solution shows where to place your variable so that a unique one is captured every time.
create a local copy of s inside your for loop and use that.
for(string s in this.Keys) {
string key = s;
//...
}
For some additional thoughts on this issue see
http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/

foreach with index [duplicate]

This question already has answers here:
How do you get the index of the current iteration of a foreach loop?
(35 answers)
Closed 9 years ago.
Is there a C# equivalent of Python's enumerate() and Ruby's each_with_index?
I keep this extension method around for this:
public static void Each<T>(this IEnumerable<T> ie, Action<T, int> action)
{
var i = 0;
foreach (var e in ie) action(e, i++);
}
And use it like so:
var strings = new List<string>();
strings.Each((str, n) =>
{
// hooray
});
Or to allow for break-like behaviour:
public static bool Each<T>(this IEnumerable<T> ie, Func<T, int, bool> action)
{
int i = 0;
foreach (T e in ie) if (!action(e, i++)) return false;
return true;
}
var strings = new List<string>() { "a", "b", "c" };
bool iteratedAll = strings.Each ((str, n)) =>
{
if (str == "b") return false;
return true;
});
You can do the following
foreach (var it in someCollection.Select((x, i) => new { Value = x, Index = i }) )
{
if (it.Index > SomeNumber) //
}
This will create an anonymous type value for every entry in the collection. It will have two properties
Value: with the original value in the collection
Index: with the index within the collection
The C# foreach doesn't have a built in index. You'll need to add an integer outside the foreach loop and increment it each time.
int i = -1;
foreach (Widget w in widgets)
{
i++;
// do something
}
Alternatively, you could use a standard for loop as follows:
for (int i = 0; i < widgets.Length; i++)
{
w = widgets[i];
// do something
}
I like being able to use foreach, so I made an extension method and a structure:
public struct EnumeratedInstance<T>
{
public long cnt;
public T item;
}
public static IEnumerable<EnumeratedInstance<T>> Enumerate<T>(this IEnumerable<T> collection)
{
long counter = 0;
foreach (var item in collection)
{
yield return new EnumeratedInstance<T>
{
cnt = counter,
item = item
};
counter++;
}
}
and an example use:
foreach (var ii in new string[] { "a", "b", "c" }.Enumerate())
{
Console.WriteLine(ii.item + ii.cnt);
}
One nice thing is that if you are used to the Python syntax, you can still use it:
foreach (var ii in Enumerate(new string[] { "a", "b", "c" }))
Aside from the LINQ answers already given, I have a "SmartEnumerable" class which allows you to get the index and the "first/last"-ness. It's a bit ugly in terms of syntax, but you may find it useful.
We can probably improve the type inference using a static method in a nongeneric type, and implicit typing will help too.
My solution involves a simple Pair class I created for general utility, and which is operationally essentially the same as the framework class KeyValuePair. Then I created a couple extension functions for IEnumerable called Ordinate (from the set theory term "ordinal").
These functions will return for each item a Pair object containing the index, and the item itself.
public static IEnumerable<Pair<Int32, X>> Ordinate<X>(this IEnumerable<X> lhs)
{
return lhs.Ordinate(0);
}
public static IEnumerable<Pair<Int32, X>> Ordinate<X>(this IEnumerable<X> lhs, Int32 initial)
{
Int32 index = initial - 1;
return lhs.Select(x => new Pair<Int32, X>(++index, x));
}
No, there is not.
As other people have shown, there are ways to simulate Ruby's behavior. But it is possible to have a type that implements IEnumerable that does not expose an index.
This is your collection
var values = new[] {6, 2, 8, 45, 9, 3, 0};
Make a range of indexes for this collection
var indexes = Enumerable.Range(0, values.Length).ToList();
Use the range to iterate with index
indexes.ForEach(i => values[i] += i);
indexes.ForEach(i => Console.Write("[{0}] = {1}", i, values[i]));
I just figured out interesting solution:
public class DepthAware<T> : IEnumerable<T>
{
private readonly IEnumerable<T> source;
public DepthAware(IEnumerable<T> source)
{
this.source = source;
this.Depth = 0;
}
public int Depth { get; private set; }
private IEnumerable<T> GetItems()
{
foreach (var item in source)
{
yield return item;
++this.Depth;
}
}
public IEnumerator<T> GetEnumerator()
{
return GetItems().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
// Generic type leverage and extension invoking
public static class DepthAware
{
public static DepthAware<T> AsDepthAware<T>(this IEnumerable<T> source)
{
return new DepthAware<T>(source);
}
public static DepthAware<T> New<T>(IEnumerable<T> source)
{
return new DepthAware<T>(source);
}
}
Usage:
var chars = new[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'}.AsDepthAware();
foreach (var item in chars)
{
Console.WriteLine("Char: {0}, depth: {1}", item, chars.Depth);
}
It depends on the class you are using.
Dictionary<(Of <(TKey, TValue>)>) Class For Example Support This
The Dictionary<(Of <(TKey, TValue>)>) generic class provides a mapping from a set of keys to a set of values.
For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair<(Of <(TKey, TValue>)>) structure representing a value and its key. The order in which the items are returned is undefined.
foreach (KeyValuePair kvp in myDictionary) {...}

Categories

Resources