Any chances to imitate times() Ruby method in C#? - c#

Every time I need to do something N times inside an algorithm using C# I write this code
for (int i = 0; i < N; i++)
{
...
}
Studying Ruby I have learned about method times() which can be used with the same semantics like this
N.times do
...
end
Code fragment in C# looks more complex and we should declare useless variable i.
I tried to write extension method which returns IEnumerable, but I am not satisfied with the result because again I have to declare a cycle variable i.
public static class IntExtender
{
public static IEnumerable Times(this int times)
{
for (int i = 0; i < times; i++)
yield return true;
}
}
...
foreach (var i in 5.Times())
{
...
}
Is it possible using some new C# 3.0 language features to make N times cycle more elegant?

A slightly briefer version of cvk's answer:
public static class Extensions
{
public static void Times(this int count, Action action)
{
for (int i=0; i < count; i++)
{
action();
}
}
public static void Times(this int count, Action<int> action)
{
for (int i=0; i < count; i++)
{
action(i);
}
}
}
Use:
5.Times(() => Console.WriteLine("Hi"));
5.Times(i => Console.WriteLine("Index: {0}", i));

It is indeed possible with C# 3.0:
public interface ILoopIterator
{
void Do(Action action);
void Do(Action<int> action);
}
private class LoopIterator : ILoopIterator
{
private readonly int _start, _end;
public LoopIterator(int count)
{
_start = 0;
_end = count - 1;
}
public LoopIterator(int start, int end)
{
_start = start;
_end = end;
}
public void Do(Action action)
{
for (int i = _start; i <= _end; i++)
{
action();
}
}
public void Do(Action<int> action)
{
for (int i = _start; i <= _end; i++)
{
action(i);
}
}
}
public static ILoopIterator Times(this int count)
{
return new LoopIterator(count);
}
Usage:
int sum = 0;
5.Times().Do( i =>
sum += i
);
Shamelessly stolen from http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html

If you are using .NET 3.5 then you can use the extension method Each proposed in this article, and use it to avoid classic loop.
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach(T item in source)
{
action(item);
}
}
}
This particular extension method spot
welds an Each method on anything that
implements IEnumerable. You know
this because the first parameter to
this method defines what this will be
inside the method body. Action is a
pre-defined class that basically
stands in for a function (delegate)
returning no value. Inside the method,
is where the elements are extracted
from the list. What this method
enables is for me to cleanly apply a
function in one line of code.
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
Hope this helps.

I wrote my own extension that add Times to Integer (plus some other stuff). You can get the code here : https://github.com/Razorclaw/Ext.NET
The code is very similar to Jon Skeet answer:
public static class IntegerExtension
{
public static void Times(this int n, Action<int> action)
{
if (action == null) throw new ArgumentNullException("action");
for (int i = 0; i < n; ++i)
{
action(i);
}
}
}

Related

How to use a Stack's Pop method in another method

I am attempting to write a program for an assignment that Pops and adds the first 2 items in a Stack. The program has a Pop method, but I would like to know how to call the method within the Add method. This Add is supposed to Pop the top two items in a stack, get their sum, and Push that sum to the stack. In my code below I call the Pop method twice inside the Add method, but when I display the stack, the stack still has all of the original values. Is there something more/else I need to go to get the Pop method to work?
class StackEmptyException : ApplicationException
{
public StackEmptyException(String message) : base(message)
{
}
}
class MathStack
{
private int[] dataStack;
private int size;
private int top = -1;
public bool IsEmpty()
{
return top == -1;
}
public bool IsFull()
{
return top == size - 1;
}
public void Push(int i)
{
dataStack[++top] = i;
}
public int Pop()
{
if (IsEmpty())
throw new StackEmptyException
("Stack empty -- cannot pop");
else
return dataStack[top--];
}
public int Top()
{
if (IsEmpty())
throw new StackEmptyException
("Stack empty -- top undefined");
else
return dataStack[top];
}
public MathStack()
{
dataStack = new int[10];
}
public MathStack(int s)
{
size = 10;
dataStack = new int[size];
}
public void LoadStack(int v)
{
dataStack[++top] = v;
}
public void Display()
{
int[] display = new int[dataStack.Length];
for (int i = 0; i < dataStack.Length; i++)
{
display[i] = dataStack[i];
Console.WriteLine("{0}", display[i]);
}
}
public void Add()
{
int add1 = dataStack[0];
int add2 = dataStack[1];
Pop();
Pop();
int sum = add1 + add2;
Console.WriteLine("Sum: {0}", sum);
}
}
class Program
{
static void Main(string[] args)
{
MathStack stack1 = new MathStack();
stack1.Push(9);
stack1.Push(8);
stack1.Push(7);
stack1.Push(6);
stack1.Push(5);
stack1.Push(4);
stack1.Push(3);
stack1.Push(2);
stack1.Push(1);
stack1.Push(0);
stack1.Display();
stack1.Add();
stack1.Display();
Console.ReadLine();
}
}
There are two things wrong with your code.
First, the Display method displays the whole array. Except that since you're not physically removing the items from the array, you need to stop at the index top:
public void Display()
{
if (IsEmpty())
{
Console.WriteLine("Empty");
return;
}
for (int i = 0; i <= top; i++)
{
Console.WriteLine(dataStack[i]);
}
}
The second issue is your Add. From what I understand, you want to pop the last two items, sum them, and push the result. In your implementation, you are actually summing the first two items (not the last two). A better version would be:
public void Add()
{
int add1 = Pop();
int add2 = Pop();
int sum = add1 + add2;
Console.WriteLine("Sum: {0}", sum);
Push(sum);
}
Notice how I do not directly access dataStack. If your API is correctly implemented, it should not be needed.

Using methods on arrays

I am very new to C#, and trying to make a program that counts an array, and I'm having trouble using methods/properties on the array (Reset, PrintCounters, Increment). the problems occur from the for loops and below. Thanks in advance if anyone is able to help.
using System;
namespace CounterTest
{
public class MainClass
{
private static void PrintCounters(Counter[] counters)
{
foreach (Counter c in counters)
{
string name = "";
int value = 0;
Console.WriteLine("{0} is {1}", name, value);
}
}
public static void Main(string[] args)
{
Counter[] myCounters = new Counter[3];
myCounters[0] = new Counter("Counter 1");
myCounters[1] = new Counter("Counter 2");
myCounters[2] = myCounters[0];
for (int i = 0; i < 4; i++)
{
Counter.Increment(myCounters[0]);
}
for (int i = 0; i < 9; i++)
{
Counter.Increment(myCounters[1]);
}
Counter.PrintCounters(myCounters);
Counter.Reset(myCounters[2]);
Counter.PrintCounters(myCounters);
}
}
}
Counter class:
using System;
using System.Collections.Generic;
using System.Text;
namespace CounterTest
{
public class Counter
{
private int _count;
private string _name;
public Counter(string name)
{
_name = name;
_count = 0;
}
public void Increment()
{
_count++;
}
public void Reset()
{
_count = 0;
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Value
{
get
{
return _count;
}
set
{
_count = value;
}
}
}
}
The methods you call are not static methods, so they are called like:
for (int i = 0; i < 4; i++)
{
myCounters[0].Increment();
}
for (int i = 0; i < 9; i++)
{
myCounters[1].Increment();
}
MainClass.PrintCounters(myCounters); //this is static
myCounters[2].Reset();
MainClass.PrintCounters(myCounters);
Counter is a type, not an instance, that's why Counter.Increment is an incorrect call (Increment is not a static method).
// Given intance of Counter - myCounters[1] call Increment() method on it
myCounters[1].Increment();
instead of
// Call static method of Counter class - Counter.Increment on instance of Counter
Counter.Increment(myCounters[1]);
etc. It can be something like this:
public static void Main(string[] args)
{
Counter[] myCounters = new Counter[3]
myCounters[0] = new Counter("Counter 1");
myCounters[1] = new Counter("Counter 2");
myCounters[2] = myCounters[0];
for (int i = 0; i < 4; i++)
{
// call Increment on myCounters[0] instance
myCounters[0].Increment();
}
for (int i = 0; i < 9; i++)
{
// call Increment on myCounters[1] instance
myCounters[1].Increment();
}
// PrintCounters method call
PrintCounters(myCounters);
// call Reset on myCounters[2] instance
myCounters[2].Reset();
// PrintCounters method call
PrintCounters(myCounters);
}
You are calling Counter.Increment and then providing a Counter as a parameter. This piece of code assumes Counter is a static class with static methods, which is not the case.
In your for loops, you should be using the code like this:
for (int i = 0; i < 4; i++)
{
myCounters[0].Increment();
}
You use Counter.Increment(myCounters[0]) like Increment was an extention method on Counter.
public static class ExtentionCounter
{
public static void Increment(this Counter cnt)
{
cnt.Value++;
}
}
When with your current definition you should use :
myCounters[0].Increment();
here is the solution for your code. Just compare with yours but see the changes are with ** .
On the PrintCounters since your looping trough the Counters as c you need to call the counter name and the valu with **c.Name and c.Value
using System;
using Test;
namespace teste
{
static class MainClass{
public static void PrintCounters(Counter[] counters)
{
foreach (Counter c in counters)
{
**string name = c.Name;**
**int value = c.Value;**
Console.WriteLine("{0} is {1}", name, value);
}
}
}
class Program
{
static void Main(string[] args)
{
Counter[] myCounters = new Counter[3];
myCounters[0] = new Counter("Counter 1");
myCounters[1] = new Counter("Counter 2");
myCounters[2] = myCounters[0];
for (int i = 0; i < 4; i++) {
**myCounters[0].Increment();**
}
for (int i = 0; i < 9; i++) {
**myCounters[1].Increment();**
}
**MainClass.PrintCounters(myCounters);**
**myCounters[2].Reset();**
**MainClass.PrintCounters(myCounters);**
}
}
}
Also since the myCounters is an instance of Counters you need to call the method of the instance like this:
myCounters[0].Increment()
Same for the other methods as Reset.
To call a static method you dont need to instantiate but in your case you need to do reference to the class to use the method PrintCounters like this:
MainClass.PrintCounters(myCounters);
Also use the keyword this.something to change instance variables.
using System;
using System.Collections.Generic;
using System.Text;
namespace Test
{
public class Counter
{
private int _count;
private string _name;
public Counter(string name)
{
**this._name = name;**
**this._count = 0;**
}
public void Increment()
{
**this._count++;**
}
public void Reset()
{
**this._count = 0;**
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Value
{
get
{
return _count;
}
set
{
_count = value;
}
}
}
}
i hope it helps

Can't Call arrays in main method

I'm practicing methods, but the problem is I want to separate inputting and sorting, the display method will be the main, I'm having trouble fixing this calling from other class.
This is my script :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CaseProblem
{
class Method
{
static void MethodInput()
{
int[] array = new int[5];
int i;
// loop for accepting values in array
for (i = 0; i < 5; i++)
{
Console.Write("Enter number:\t");
array[i] = int.Parse(Console.ReadLine());
}
}
public static void MethodSort()
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
}
class Program
{
static void Main(int[]array)
{
//sorting array value;
Array.Sort(array); //use array's sort function
Method.MethodSort(array);
Console.ReadLine();
}
}
}
Thank you for your help
First of all Main() ( or "EntryPoint" as we should call it ) cannot have int[] as an input parameter but string[] instead you should learn basics of programming before starting to actually code something.
Second thing :
I want to separate inputting and sorting
You can create an object called Input
public class Input
{
public static void Write(string message)
{
Console.WriteLine(message);
}
public static int? ReadInt(string reason)
{
Write(reason);
string userInput = Console.ReadLine();
int parsed = 0;
if(int.TryParse(userInput, out parsed))
return (int?)parsed;
return null;
}
}
This will be your "InputLogic" which you can use as Input.ReadInt("Please specify your age: ");
Next you can make an Operations object :
public class Operations
{
public void Display(int[] arr)
{
foreach(int i in arr)
{
// and since you have "Input" class that can display things
Input.Write(i.ToString());
}
}
public void Sort(ref int[] arr)
{
Array.Sort(arr);
}
}
Now the last thing is to combine it within your Program
class Program
{
static void Main(string[] args)
{
int[] arr = new int[5];
for(int i = 0; i < arr.Length; i++)
{
int? input = null;
while( !( input = Input.ReadInt("Give me number") ).HasValue ) { }
arr[i] = input.Value;
}
Operations op = new Operations();
op.Display(arr);
op.Sort(ref arr);
op.Display(arr);
}
}
Well, you are missing the parameter for the called function.
public static void MethodSort(int[] array)
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
note: not tested
Okay, you have two errors, both in this method:
public static void MethodSort()
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
as well as how you call it:
Method.MethodSort(array);
The first problem is that the method uses the variable array, which doesn't exist in that method's scope.
The second problem is that you are passing array to the call to Method.MethodSort, but that method isn't configured to take a parameter.
There are two ways to approach solving this: remove array entirely, or change the method to accept it. Now, you obviously cannot remove array, as the whole point is to do stuff with it. Therefore, the logical solution is to add array as a parameter to your method:
public static void MethodSort(int[] array)
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}

Convert Ruby's times to C#

I am trying to convert Ruby's time to C#, but I am stuck now.
Here's my try:
public static class Extensions
{
public static void Times(this Int32 times, WhatGoesHere?)
{
for (int i = 0; i < times; i++)
???
}
}
I am new to C#, and maybe this one should be easy, and I know I want to use Extensionmethods. But since functions are not 'first class ' in C#, I am stuck for now.
So, what parametertype should I use for of WhatGoesHere?
You can use the Action type:
public static class Extensions
{
public static void Times(this Int32 times, Action<Int32> action)
{
for (int i = 0; i < times; i++)
action(i);
}
}
class Program
{
delegate void Del();
static void Main(string[] args)
{
5.Times(Console.WriteLine);
// or
5.Times(i => Console.WriteLine(i));
}
}
Also have a look here to learn about delegates.

Faster enumeration: Leveraging Array Enumeration

So, I have a class with an array inside. Currently, my strategy for enumerating over the class's items is to use the code, foreach (item x in classInstance.InsideArray) . I would much rather use foreach (item x in classInstance) and make the array private. My main concern is that I really need to avoid anything slow; the array gets hit a lot (and has a couple hundred items). It is vital that enumerating over this array is cheap. One thought was to just have the class implement IEnumerable<item>, but InsideArray.getEnumerator() only gives me a non-generic enumerator. I also tried implementing the IEnumerable interface. This worked but was very slow, possibly due to boxing.
Is there a way to make the class itself enumerable without a performance hit?
Normal Code:
//Class
public class Foo {
//Stuff
public Item[,] InsideArray {get; private set;}
}
//Iteration. Shows up all over the place
foreach (Item x in classInstance.InsideArray)
{
//doStuff
}
Adjusted, much slower code:
//Class
public class Foo : IEnumerable {
//Stuff
private Item[,] InsideArray;
System.Collections.IEnumerator System.Collections.IEnumerable GetEnumerator()
{
return InsideArray.GetEnumerator();
}
}
//Iteration. Shows up all over the place
foreach (Item x in classInstance)
{
//doStuff
}
Note: Adding an implementation for the nongeneric iterator is possible and faster than my slow solution, but it is still a bit worse than just using the array directly. I was hoping there was a way to somehow tell C#, "hey, when I ask you to iterate over this object iterate over it's array, just as fast," but apparently that is not quite possible...at least from the answers suggested thus far.
A bespoke iterator might make it quicker (edited to return as known type):
Basic: 2468ms - -2049509440
Bespoke: 1087ms - -2049509440
(you would use the ArrayIterator directly as Foo's GetEnumerator - essentially copying the code from ArrayEnumerator.GetEnumerator; my point is to show that a typed iterator is faster than the interface)
With code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
class Foo
{
public struct ArrayIterator<T> : IEnumerator<T>
{
private int x, y;
private readonly int width, height;
private T[,] data;
public ArrayIterator(T[,] data)
{
this.data = data;
this.width = data.GetLength(0);
this.height = data.GetLength(1);
x = y = 0;
}
public void Dispose() { data = null; }
public bool MoveNext()
{
if (++x >= width)
{
x = 0;
y++;
}
return y < height;
}
public void Reset() { x = y = 0; }
public T Current { get { return data[x, y]; } }
object IEnumerator.Current { get { return data[x, y]; } }
}
public sealed class ArrayEnumerator<T> : IEnumerable<T>
{
private readonly T[,] arr;
public ArrayEnumerator(T[,] arr) { this.arr = arr; }
public ArrayIterator<T> GetEnumerator()
{
return new ArrayIterator<T>(arr);
}
System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public int[,] data;
public IEnumerable<int> Basic()
{
foreach (int i in data) yield return i;
}
public ArrayEnumerator<int> Bespoke()
{
return new ArrayEnumerator<int>(data);
}
public Foo()
{
data = new int[500, 500];
for (int x = 0; x < 500; x++)
for (int y = 0; y < 500; y++)
{
data[x, y] = x + y;
}
}
static void Main()
{
Test(1); // for JIT
Test(500); // for real
Console.ReadKey(); // pause
}
static void Test(int count)
{
Foo foo = new Foo();
int chk;
Stopwatch watch = Stopwatch.StartNew();
chk = 0;
for (int i = 0; i < count; i++)
{
foreach (int j in foo.Basic())
{
chk += j;
}
}
watch.Stop();
Console.WriteLine("Basic: " + watch.ElapsedMilliseconds + "ms - " + chk);
watch = Stopwatch.StartNew();
chk = 0;
for (int i = 0; i < count; i++)
{
foreach (int j in foo.Bespoke())
{
chk += j;
}
}
watch.Stop();
Console.WriteLine("Bespoke: " + watch.ElapsedMilliseconds + "ms - " + chk);
}
}
Cast your array to IEnumerable<item> before calling GetEnumerator() and you'll get the generic IEnumerator. For example:
string[] names = { "Jon", "Marc" };
IEnumerator<string> enumerable = ((IEnumerable<string>)names).GetEnumerator();
It may well still be a bit slower than enumerating the array directly with foreach (which the C# compiler does in a different way) but at least you won't have anything else in the way.
EDIT:
Okay, you said your other attempt used an indexer. You could try this approach, although I don't think it'll be any faster:
public IEnumerable<Item> Items
{
get
{
foreach (Item x in items)
{
yield return x;
}
}
}
An alternative would be to try to avoid using a two-dimensional array to start with. Is that an absolute requirement? How often are you iterating over a single array after creating it? It may be worth taking a slight hit at creation time to make iteration cheaper.
EDIT: Another suggestion, which is slightly off the wall... instead of passing the iterator back to the caller, why not get the caller to say what to do with each item, using a delegate?
public void ForEachItem(Action action)
{
foreach (Item item in items)
{
action(item);
}
}
Downsides:
You incur the penalty of a delegate call on each access.
It's hard to break out of the loop (other than by throwing an exception). There are different ways of approaching this, but let's cross that bridge when we come to it.
Developers who aren't familiar with delegates may get a bit confused.
How about adding an indexer to the class:
public MyInsideArrayType this[int index]
{
get{return this.insideArray[index];
}
And if you REALLY need foreach capabilities:
public IEnumerable<MyInsideArrayType> GetEnumerator()
{
for(int i = 0; i<this.insideArray.Count;i++)
{
yield return this[i];
}
}
All forms of iteration are cheap. If anyone in this day-and-age managed to somehow write and publish an expensive iterator they would be (rightly) burned at the stake.
Premature optimization is evil.
Cheers. Keith.

Categories

Resources