int i = 0;
foreach (var logInAlarm in logInAlarms)
{
//Custom Code
//For comparison reason i need to access the next logInAlarm in the list.
var nextDate = logInAlarms[i + 1].Date;
i++;
}
I came up with an idea to add a counter variable and later access the element using that counter. Is this the best way?
You are better using the existing for loop which can stop an out of bounds error, but your approach is more or less correct
for(int i = 0; i < logInAlarms.Length - 1; i++)
var nextDate = logInAlarms[i+1].Date;
Test code for the end of array
var arr = Enumerable.Range(0, 5).ToArray();
for (int i = 0; i < arr.Length - 1; i++)
Console.Write(arr[i]);
Console.ReadLine();
Because you're dealing with a collection that has an indexer property accepting an integer (for instance an array or List<T>), you should use a for loop.
for (int v = 1; v < logInAlarms.Length; v++)
{
var current = logInAlarms[v - 1];
var next = logInAlarms[v];
// use current and next
}
However, if you weren't dealing with an array or List<T> and were instead using any sort of IEnumerable as the foreach loop supports, I would use this more generalized code.
var enumerator = logInAlarms.GetEnumerator();
if(enumerator.MoveNext())
{
var current = enumerator.Current;
while (enumerator.MoveNext())
{
var next = enumerator.Current;
// use current and next
current = next;
}
// current is now the last node, to which there is no "next." Deal with that or ignore it as you see so fit.
}
I suggest this, again, only because it will work any time that a foreach does, whereas a for loop will only work in certain instances (ElementAt notwithstanding). If you can use a for, do, but if you can't, this will work.
Just for fun, you could even write a helper function. You'd need to use Enumerable.Cast<T> if your original type implemented IEnumerable and not IEnumerable<T>, but this would still be pretty useful if you do a lot like this. I've also implemented a using block as suggested by #JeppeStigNielsen in a comment here, you may or may not want to do that in the first example, depending on whether your implementation implements IEnumerable<T> rather than IEnumerable (which is being phased out anyway, and is barely used).
public IEnumerable<Tuple<T, T>> GetPairs<T>(IEnumerable<T> coll)
{
using (var enumerator = logInAlarms.GetEnumerator())
{
if(enumerator.MoveNext())
{
var current = enumerator.Current;
while (enumerator.MoveNext())
{
var next = enumerator.Current;
yield return new Tuple<T, T>(current, next);
current = next;
}
}
}
}
Related
I'm trying to use the Array.ForEach() extension method to loop through for a list of filtered elements from an array and then modify those values, unfortunately that doesn't seem to work I'm guessing because it doesn't actually modify the reference value of each element.
Is there any way to do this besides storing the results of the Array.ForEach() into a seperate array and then cloning that array to the original array? Also I know I could obviously do all of this without cloning if I use a for loop but if I could do it this way it would be cleaner and would be less code.
Here's the snippet:
Array.ForEach(Array.FindAll(starts, e => e < 0), e => e = 0);
ForEach simply isn't intended to do this - just like you wouldn't be able to do this with a foreach loop.
Personally I'd just use a for loop - it's easy to read and clear:
for (int i = 0; i < array.Length; i++)
{
// Alternatively, use Math.Max to pull up any negative values to 0
if (array[i] < 0)
{
array[i] = 0;
}
}
It really is simple - anyone will be able to understand it.
Now you could write your own extension method instead. You could write one to replace all values which satisfy a predicate with a fixed value, or you could write one to replace all values entirely... but I don't think it's really worth it. As an example of the latter:
public static void ReplaceElements<T>(this T[] array,
Func<T, T> replacementFunction)
{
// TODO: Argument validation
for (int i = 0; i < array.Length; i++)
{
array[i] = replacementFunction(array[i]);
}
}
Then call it with:
starts.ReplaceElements(x => Math.Max(x, 0));
I'd personally still use the for loop though.
(You could potentially change the above very slightly to make it take IList<T> and use Count instead. That would still work with arrays, but also List<T> etc too.)
You can do that with ref and delegates. However, I don't think it adds much value.
public delegate void RefAction<T>(ref T value);
public static void ForEachRef<T>(this T[] array, RefAction<T> action)
{
for (int i = 0; i < array.Length; ++i) action(ref array[i]);
}
You can use it as follows:
var myArray = new int[];
myArray.ForEachRef((ref int i) => i = whateverYouLike());
From the standpoint of possibility, there could be an interface IRefEnumerable<T> which iterates some container with assignable elements.
array = array.Select(x => (x < 0) ? 0: x).ToArray();
I have created an ienumerable of lambda functions using this function
static IEnumerable<Func<int>> MakeEnumerator(int[] values)
{
for (int a = 0; a < values.Length; a++)
{
yield return () => Values[a];
}
}
I cannot then reverse this using LINQ or convert into an array without all the values becoming the last function.
Example code (note this just demonstrates the problem it is not the code in the application):
int[] start = {1,2,3};
IEnumerable<Func<int>> end = MakeEnumerator(start).Reverse<Func<int>>();
foreach (Func<int> i in end)
{
Console.WriteLine(i());
}
I think the problem is in the MakeEnumerator function. How would I modify this to make it work or go about writing a working replacement reverse function.
The problem is that you're capturing the loop variable. All of your delegates are capturing the same variable, so they'll always see the latest value of a... which will be values.Length + 1 by the time you're executing the delegates, in your use cases. You can simply copy it instead:
for (int a = 0; a < values.Length; a++)
{
int copy = a;
yield return () => Values[copy];
}
Alternatively (and preferrably IMO) use a foreach loop, which currently requires the same workaround:
foreach (int value in values)
{
int copy = value;
yield return () => copy;
}
Or better yet:
return values.Select(x => (Func<int>)(() => x));
Or:
Func<int, Func<int>> projection = x => () => x;
return values.Select(projection);
See Eric Lippert's blog post "Closing over the loop variable considered harmful" for more information. Note that the behaviour of foreach may well be changing for C# 4.5.
All of your lambda expressions are sharing the same a variable.
Since you're only calling them after the loop finishes, a is always 3.
You need to give each one its own variable:
for (int dontUse = 0; dontUse < values.Length; dontUse++)
{
int a = dontUse;
yield return () => Values[a];
}
In this code, each lambda expression gets its own a variable (since it's scoped inside the loop), and these separate variables never change.
The algorithm creates all possible variants of the sequence from variants for each member of the sequence.
C# code :
static void Main(string[] args)
{
var arg = new List<List<int>>();
int i = 0;
for (int j = 0; j < 5; j++)
{
arg.Add(new List<int>());
for (int j1 = i; j1 < i + 3; j1++)
{
//if (j1 != 5)
arg[j].Add(j1);
}
i += 3;
}
List<Utils<int>.Variant<int>> b2 = new List<Utils<int>.Variant<int>>();
//int[][] bN;
var s = System.Diagnostics.Stopwatch.StartNew();
//for(int j = 0; j < 10;j++)
b2 = Utils<int>.Produce2(arg);
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
}
public class Variant<T>
{
public T element;
public Variant<T> previous;
}
public static List<Variant<T>> Produce2(List<List<T>> input)
{
var ret = new List<Variant<T>>();
foreach (var form in input)
{
var newRet = new List<Variant<T>>(ret.Count * form.Count);
foreach (var el in form)
{
if (ret.Count == 0)
{
newRet.Add(new Variant<T>{ element = el, previous = null });
}
else
{
foreach (var variant in ret)
{
var buf = new Variant<T> { previous = variant, element = el };
newRet.Add(buf);
}
}
}
ret = newRet;
}
return ret;
}
Scala code :
object test {
def main() {
var arg = new Array[Array[Int]](5)
var i = 0
var init = 0
while (i<5)
{
var buf = new Array[Int](3)
var j = 0
while (j<3)
{
buf(j) = init
init = init+1
j = j + 1
}
arg(i)=buf
i = i + 1
}
println("Hello, world!")
val start = System.currentTimeMillis
var res = Produce(arg)
val stop = System.currentTimeMillis
println(stop-start)
/*for(list <- res)
{
for(el <- list)
print(el+" ")
println
}*/
println(res.length)
}
def Produce[T](input:Array[Array[T]]):Array[Variant[T]]=
{
var ret = new Array[Variant[T]](1)
for(val forms <- input)
{
if(forms!=null)
{
var newRet = new Array[Variant[T]](forms.length*ret.length)
if(ret.length>0)
{
for(val prev <-ret)
if(prev!=null)
for(val el <-forms)
{
newRet = newRet:+new Variant[T](el,prev)
}
}
else
{
for(val el <- forms)
{
newRet = newRet:+new Variant[T](el,null)
}
}
ret = newRet
}
}
return ret
}
}
class Variant[T](var element:T, previous:Variant[T])
{
}
As others have said, the difference is in how you're using the collections. Array in Scala is the same thing as Java's primitive array, [], which is the same as C#'s primitive array []. Scala is clever enough to do what you ask (namely, copy the entire array with a new element on the end), but not so clever as to tell you that you'd be better off using a different collection. For example, if you just change Array to ArrayBuffer it should be much faster (comparable to C#).
Actually, though, you'd be better off not using for loops at all. One of the strengths of Scala's collections library is that you have a wide variety of powerful operations at your disposal. In this case, you want to take every item from forms and convert it into a Variant. That's what map does.
Also, your Scala code doesn't seem to actually work.
If you want all possible variants from each member, you really want to use recursion. This implementation does what you say you want:
object test {
def produce[T](input: Array[Array[T]], index: Int = 0): Array[List[T]] = {
if (index >= input.length) Array()
else if (index == input.length-1) input(index).map(elem => List(elem))
else {
produce(input, index+1).flatMap(variant => {
input(index).map(elem => elem :: variant)
})
}
}
def main() {
val arg = Array.tabulate(5,3)((i,j) => i*3+j)
println("Hello, world!")
val start = System.nanoTime
var res = produce(arg)
val stop = System.nanoTime
println("Time elapsed (ms): " + (stop-start)/1000000L)
println("Result length: " + res.length)
println(res.deep)
}
}
Let's unpack this a little. First, we've replaced your entire construction of the initial variants with a single tabulate instruction. tabulate takes a target size (5x3, here), and then a function that maps from the indices into that rectangle into the final value.
We've also made produce a recursive function. (Normally we'd make it tail-recursive, but let's keep things as simple as we can for now.) How do you generate all variants? Well, all variants is clearly (every possibility at this position) + (all variants from later positions). So we write that down recursively.
Note that if we build variants recursively like this, all the tails of the variants end up the same, which makes List a perfect data structure: it's a singly-linked immutable list, so instead of having to copy all those tails over and over again, we just point to them.
Now, how do we actually do the recursion? Well, if there's no data at all, we had better return an empty array (i.e. if index is past the end of the array). If we're on the last element of the array of variations, we basically want each element to turn into a list of length 1, so we use map to do exactly that (elem => List(elem)). Finally, if we are not at the end, we get the results from the rest (which is produce(input, index+1)) and make variants with each element.
Let's take the inner loop first: input(index).map(elem => elem :: variant). This takes each element from variants in position index and sticks them onto an existing variant. So this will give us a new batch of variants. Fair enough, but where do we get the new variant from? We produce it from the rest of the list: produce(input, index+1), and then the only trick is that we need to use flatMap--this takes each element, produces a collection out of it, and glues all those collections together.
I encourage you to throw printlns in various places to see what's going on.
Finally, note that with your test size, it's actually an insigificant amount of work; you can't accurately measure that, even if you switch to using the more accurate System.nanoTime as I did. You'd need something like tabulate(12,3) before it gets significant (500,000 variants produced).
The :+ method of the Array (more precisely of ArrayOps) will always create a copy of the array. So instead of a constant time operation you have one that is more or less O(n).
You do it within nested cycles => your whole stuff will be an order of magnitude slower.
This way you more or less emulate an immutable data structure with a mutable one (which was not designed for it).
To fix it you can either use Array as a mutable data structure (but then try to avoid endless copying), or you can switch to a immutable one. I did not check your code very carefully, but the first bet is usually List, check the scaladoc of the various methods to see their performance behaviour.
ret.length is not 0 all the time, right before return it is 243. The size of array should not be changed, and List in .net is an abstraction on top of array. BUT thank you for the point - problem was that I used :+ operator with array which as I understand caused implicit use of type LinkedList
atm I do it like this:
lock (LockObj)
{
foreach (var o in Oo)
{
var val = o.DateActive;
if (val.AddSeconds(30) < DateTime.Now) Oo.Remove(o);
}
}
and I get this error:
Collection was modified; enumeration operation may not execute
how this should be done?
You have to use a regular for loop.
for (int i = 0; i < Oo.Length; ++i)
{
var val = Oo[i];
if (val.AddSeconds(30) < DateTime.Now)
{
Oo.RemoveAt(i);
i--; // since we just removed an element
}
}
The reason you cannot edit a collection with a foreach loop is because foreach uses a readonly IEnumerator of the collection you are iterating.
you can't modify a collection you are enumerating..
to change it get a copy of it and change it.
for(var k in OO.ToList())
.....
or
use count and iterate the collection with index,
for (int i=0;i<OO.Count();i++)
.....
You simply cannot modify the collection if you are iterating with foreach. You have two options, Loop with For instead of foreach or create another Collection and modify that.
This problem is completely unrelated to locking.
If you add/remove elements from a List all iterators pointing to that list become invalid.
One alternative to using an iterator is manually working with indices. Then you can iterate backwards and remove elements with RemoveAt.
for(int i=Oo.Count-1;i>=0;i--)
{
var o=Oo[i];
if (o.DateActive.AddSeconds(30)<DateTime.Now)
Oo.RemoveAt(i);
}
Unfortunately this native implementation is O(n^2). If you write it in a more complex way where you first assign the elements to their new position and then truncate the list it becomes O(n).
Buf if Oo is a List<T> there is a much better solution. You can use Oo.RemoveAll(o=>o.DateActive.AddSeconds(30)<DateTime.Now). Unfortunately you there is no such extension method on IList<T> by default.
I'd write the code like this:
lock (LockObj)
{
DateTime deleteTime=DateTime.Now.AddSeconds(-30);
Oo.RemoveAll(o=>o.DateActive<deleteTime);
}
As a sidenote I'd personally use UTC times instead of local times for such code.
class Program
{
static void Main(string[] args)
{
List<OOItem> oo = new List<OOItem>();
oo.Add( new OOItem() { DateActive = DateTime.Now.AddSeconds(-31) });
lock(LockObj)
{
foreach( var item in oo.Where( ooItem => ooItem.DateActive.AddSeconds(30) < DateTime.Now ).ToArray())
{
oo.Remove(item);
}
}
Debug.Assert( oo.Count == 0);
}
}
public class OOItem
{
public DateTime DateActive { get; set; }
}
I'm going to suggest an approach that avoids messing around with decrementing loop indexes and other stuff that makes code difficult to understand.
I think the best bet is to write a nice query and then do a foreach over the result of turning the query into an array:
var inactives = from o in Oo
where o.DateActive < DateTime.Now
select o;
foreach (var o in inactives.ToArray())
{
Oo.Remove(o);
}
This avoids the issue of the collection changing and makes the code quite a bit more readable.
If you're a little more "functionally" oriented then here's another choice:
(from o in Oo
where o.DateActive < DateTime.Now
select o)
.ToList()
.ForEach(o => Oo.Remove(o));
Enjoy!
The problem is not related to the lock.
Use a for() loop instead of foreach().
I can't 100% replace your code because your code provides no hint of what collection type "Oo" is. Neither does the name "Oo". Perhaps one of the evils of var keyword overuse? Or maybe I just can't see enough of your code ;)
int size = Oo.Length();
for(int i = 0; i < size; i++){
if (Oo[i].AddSeconds(30) < DateTime.Now){
Oo[i].RemoveAt(i);
size--; // Compensate for new size after removal.
}
}
you can use Parallel.ForEach(oO, val=> { oO.Remove(val); })
Parallel doesn't have the IEnumerator problem !
What is the best way to iterate through a strongly-typed generic List in C#.NET and VB.NET?
For C#:
foreach(ObjectType objectItem in objectTypeList)
{
// ...do some stuff
}
Answer for VB.NET from Purple Ant:
For Each objectItem as ObjectType in objectTypeList
'Do some stuff '
Next
With any generic implementation of IEnumerable the best way is:
//C#
foreach( var item in listVariable) {
//do stuff
}
There is an important exception however. IEnumerable involves an overhead of Current() and MoveNext() that is what the foreach loop is actually compiled into.
When you have a simple array of structs:
//C#
int[] valueTypeArray;
for(int i=0; i < valueTypeArray.Length; ++i) {
int item = valueTypeArray[i];
//do stuff
}
Is quicker.
Update
Following a discussion with #Steven Sudit (see comments) I think my original advice may be out of date or mistaken, so I ran some tests:
// create a list to test with
var theList = Enumerable.Range(0, 100000000).ToList();
// time foreach
var sw = Stopwatch.StartNew();
foreach (var item in theList)
{
int inLoop = item;
}
Console.WriteLine("list foreach: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
// time for
int cnt = theList.Count;
for (int i = 0; i < cnt; i++)
{
int inLoop = theList[i];
}
Console.WriteLine("list for : " + sw.Elapsed.ToString());
// now run the same tests, but with an array
var theArray = theList.ToArray();
sw.Reset();
sw.Start();
foreach (var item in theArray)
{
int inLoop = item;
}
Console.WriteLine("array foreach: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
// time for
cnt = theArray.Length;
for (int i = 0; i < cnt; i++)
{
int inLoop = theArray[i];
}
Console.WriteLine("array for : " + sw.Elapsed.ToString());
Console.ReadKey();
So, I ran this in release with all optimisations:
list foreach: 00:00:00.5137506
list for : 00:00:00.2417709
array foreach: 00:00:00.1085653
array for : 00:00:00.0954890
And then debug without optimisations:
list foreach: 00:00:01.1289015
list for : 00:00:00.9945345
array foreach: 00:00:00.6405422
array for : 00:00:00.4913245
So it appears fairly consistent, for is quicker than foreach and arrays are quicker than generic lists.
However, this is across 100,000,000 iterations and the difference is about .4 of a second between the fastest and slowest methods. Unless you're doing massive performance critical loops it just isn't worth worrying about.
C#
myList<string>().ForEach(
delegate(string name)
{
Console.WriteLine(name);
});
Anonymous delegates are not currently implemented in VB.Net, but both C# and VB.Net should be able to do lambdas:
C#
myList<string>().ForEach(name => Console.WriteLine(name));
VB.Net
myList(Of String)().ForEach(Function(name) Console.WriteLine(name))
As Grauenwolf pointed out the above VB won't compile since the lambda doesn't return a value. A normal ForEach loop as others have suggested is probably the easiest for now, but as usual it takes a block of code to do what C# can do in one line.
Here's a trite example of why this might be useful: this gives you the ability to pass in the loop logic from another scope than where the IEnumerable exists, so you don't even have to expose it if you don't want to.
Say you have a list of relative url paths that you want to make absolute:
public IEnumerable<String> Paths(Func<String> formatter) {
List<String> paths = new List<String>()
{
"/about", "/contact", "/services"
};
return paths.ForEach(formatter);
}
So then you could call the function this way:
var hostname = "myhost.com";
var formatter = f => String.Format("http://{0}{1}", hostname, f);
IEnumerable<String> absolutePaths = Paths(formatter);
Giving you "http://myhost.com/about", "http://myhost.com/contact" etc. Obviously there are better ways to accomplish this in this specfic example, I'm just trying to demonstrate the basic principle.
For VB.NET:
For Each tmpObject as ObjectType in ObjectTypeList
'Do some stuff '
Next
Without knowing the internal implementation of a list, I think generally the best way to iterate over it would be a foreach loop. Because foreach uses an IEnumerator to walk over the list, it's up to the list itself to determine how to move from object to object.
If the internal implementation was, say, a linked list, then a simple for loop would be quite a bit slower than a foreach.
Does that make sense?
It depends on your application:
for loop, if efficiency is a priority
foreach loop or ForEach method, whichever communicates your intent more clearly
I may be missing something, but iterating through a generic list should be fairly simple if you use my examples below. The List<> class implements the IList and IEnumerable interfaces so that you can easily iterate through them basically any way you want.
The most efficient way would be to use a for loop:
for(int i = 0; i < genericList.Count; ++i)
{
// Loop body
}
You may also choose to use a foreach loop:
foreach(<insertTypeHere> o in genericList)
{
// Loop body
}