In computational programs there is often such code as
foreach (var x in xx)
foreach (var y in yy)
foreach (var z in zz)
Calculate(x, y, z);
Can it be simplified to just one loop, like
foreach (var (x, y, z) in F(xx, yy, zz)) Calculate(x, y, z);
For any number of variables, probably having different types?
If you want to deal with arbitrary types, you will have to define a generic method for all each amount of parameters you have - this is the same problem as with the predefined delagates Action, Action<T>, Action<T1,T2>, ...
Hence your code could look like this
public static class Helper
{
public static IEnumerable<(T1,T2)> CrossJoin<T1,T2>(IEnumerable<T1> input1, IEnumerable<T2> input2)
{
return input1.SelectMany(x => input2, (x,y) => (x,y));
}
public static IEnumerable<(T1,T2,T3)> CrossJoin<T1,T2,T3>(IEnumerable<T1> input1, IEnumerable<T2> input2, IEnumerable<T3> input3)
{
return CrossJoin(input1,input2).SelectMany(x => input3, (x,y) => (x.Item1, x.Item2, y));
}
public static IEnumerable<(T1,T2,T3,T4)> CrossJoin<T1,T2,T3,T4>(IEnumerable<T1> input1, IEnumerable<T2> input2, IEnumerable<T3> input3, IEnumerable<T4> input4)
{
return CrossJoin(input1,input2,input3).SelectMany(x => input4, (x,y) => (x.Item1, x.Item2, x.Item3, y));
}
// and so on
}
Because we have to define a method for every amount of parameters, there is no need for a sophisticated recursive method which catches all cases. Because only value tuples are used and no arrays are created, the garbage collection won't have so much work as in your solution.
Online demo: https://dotnetfiddle.net/HrkhX6
I have come up with a simple cross join method, but all variables should have the same type T:
public static IEnumerable<T[]> CrossJoin<T>(params IEnumerable<T>[] seqs)
{
if (seqs.Length == 1) foreach (var x in seqs[0]) yield return new[] { x };
else
{
var subres = CrossJoin(seqs.Skip(1).ToArray());
var res = from x in seqs[0] from xx in subres select xx.Prepend(x);
foreach (var x in res) yield return x.ToArray();
}
}
usage:
foreach (var (x, y, z) in Helper.CrossJoin(xx, yy, zz)) Calculate(x, y, z);
It can be changed to work with object but it will require type casting to use the variables..
Related
There is a method that receives a ValueTuple and returns it after modifying it. In this case, can I specify the field name of the ValueTuple in the method parameter?
private static void Operation()
{
var tuple = (X: 10, Y: 20);
var changeTuple = ChangeTuple(tuple);
}
private static ValueTuple<int, int> ChangeTuple(ValueTuple<int, int> tuple)
{
tuple.Item1 = 100; // ex) tuple.X = 100;
tuple.Item2 = 200; // ex) tuple.Y = 200;
return tuple;
}
Yes, you can simply replace ValueTuple<int, int> to (int X, int Y):
private static (int X, int Y) ChangeTuple((int X, int Y) tuple)
{
tuple.X = 100;
tuple.Y = 200;
return tuple;
}
For reference: naming tuple's fields
Or you can use deconstruction:
private static (int X, int Y) ChangeTuple(ValueTuple<int, int> tuple)
{
var (X, Y) = tuple;
X = 100;
Y = 200;
return (X, Y);
}
Please note that in both cases you are not modifying the original ValueTuple rather create a new one:
In the first case it is because the ValueTuple is a struct, so it is passed by value
In the second case we explicitly create a new named ValueTuple
I am trying to port some code from Python to C#.
The goal is to compare adjacent elements and see if four consecutive values are bigger than one another.
Following this post (Compare two adjacent elements in same list) I was able to use pairwise on a deque to succesfully compare adjacent elements.
//In python
from more_itertools import pairwise
for x, y in pairwise(a_deque):
if (x < y):
i += 1
if (i == 4)
print("Hello world!")
The problem is that C# does not contain the more_itertools library so I am currently looking for a similar technique to achieve the same solution.
FYI. The deque implementation is from https://www.nuget.org/packages/Nito.Collections.Deque/
Any suggestions?
You can implement the python pairwise method yourself like this:
public static IEnumerable<(T, T)> Pairwise<T>(IEnumerable<T> collection)
{
using (var enumerator = collection.GetEnumerator())
{
enumerator.MoveNext();
var previous = enumerator.Current;
while (enumerator.MoveNext())
{
yield return (previous, enumerator.Current);
previous = enumerator.Current;
}
}
}
Then the algorithm in c# is structural very similar to the python version:
static void Main(string[] args)
{
var values = new[] { 5, 7, 8, 9, 10, 10, 8, 2, 1 };
var i = 0;
foreach (var (x, y) in Pairwise(values))
{
if (x < y)
{
i++;
if (i == 4)
Console.WriteLine("Hello world!");
}
}
Console.ReadLine();
}
There is a project called MoreLINQ with clever LINQ extensions. Most of the time though the code is really simple thanks to LINQ's simplicity. You can add it as a NuGet package or as individual source packages that add just the operators you want.
Pairwise.cs implements an operator that can apply a function to pairs of elements :
int[] numbers = { 123, 456, 789 };
var result = numbers.Pairwise((a, b) => a + b);
The source is really simple - retrieve an item and if we haven't reached the end, retrieve another one and apply the function :
public static IEnumerable<TResult> Pairwise<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TSource, TResult> resultSelector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
return _();
IEnumerable<TResult> _()
{
using (var e = source.GetEnumerator())
{
if (!e.MoveNext())
yield break;
var previous = e.Current;
while (e.MoveNext())
{
yield return resultSelector(previous, e.Current);
previous = e.Current;
}
}
}
}
The only "trick" is the use of the local iterator function named ... _
You can thing of the Pairwise operator as an optimized Window operator for just 2 items.
There's another Window operator that can return sequences of N items.
This expression :
var x=Enumerable.Range(1,5).Window(3);
Produces the following arrays :
{1,2,3}
{2,3,4}
{3,4,5}
Just create the function:
static IEnumerable<(T, T)> PairWise<T>(IEnumerable<T> collection)
{
var queue = new Queue<T>();
foreach (T item in collection)
{
queue.Enqueue(item);
if (queue.Count == 2)
{
T x = queue.Dequeue();
T y = queue.Peek();
yield return (x, y);
}
}
}
and use it:
foreach ((int x, int y) in PairWise(new[] {1, 2, 3, 4, 5}))
{
Console.WriteLine($"{x} {y}");
}
You could try like this:
for (int i = 0; i < arr.Length - 1; ++i)
{
int a = arr[i];
int b = arr[i + 1];
Console.WriteLine($"{a} {b}");
}
I have a double[] array, i want to use it as key (not literally, but in the way that the key is matched when all the doubles in the double array need to be matched)
What is the fastest way to use the double[] array as key to dictionary?
Is it using
Dictionary<string, string> (convert double[] to a string)
or
anything else like converting it
Given that all key arrays will have the same length, either consider using a Tuple<,,, ... ,>, or use a structural equality comparer on the arrays.
With tuple:
var yourDidt = new Dictionary<Tuple<double, double, double>, string>();
yourDict.Add(Tuple.Create(3.14, 2.718, double.NaN), "da value");
string read = yourDict[Tuple.Create(3.14, 2.718, double.NaN)];
With (strongly typed version of) StructuralEqualityComparer:
class DoubleArrayStructuralEqualityComparer : EqualityComparer<double[]>
{
public override bool Equals(double[] x, double[] y)
{
return System.Collections.StructuralComparisons.StructuralEqualityComparer
.Equals(x, y);
}
public override int GetHashCode(double[] obj)
{
return System.Collections.StructuralComparisons.StructuralEqualityComparer
.GetHashCode(obj);
}
}
...
var yourDict = new Dictionary<double[], string>(
new DoubleArrayStructuralEqualityComparer());
yourDict.Add(new[] { 3.14, 2.718, double.NaN, }, "da value");
string read = yourDict[new[] { 3.14, 2.718, double.NaN, }];
Also consider the suggestion by Sergey Berezovskiy to create a custom class or (immutable!) struct to hold your set of doubles. In that way you can name your type and its members in a natural way that makes it more clear what you do. And your class/struct can easily be extended later on, if needed.
Thus all arrays have same length and each item in array have specific meaning, then create class which holds all items as properties with descriptive names. E.g. instead of double array with two items you can have class Point with properties X and Y. Then override Equals and GetHashCode of this class and use it as key (see What is the best algorithm for an overriding GetHashCode):
Dictionary<Point, string>
Benefits - instead of having array, you have data structure which makes its purpose clear. Instead of referencing items by indexes, you have nice named property names, which also make their purpose clear. And also speed - calculating hash code is fast. Compare:
double[] a = new [] { 12.5, 42 };
// getting first coordinate a[0];
Point a = new Point { X = 12.5, Y = 42 };
// getting first coordinate a.X
[Do not consider this a separate answer; this is an extension of #JeppeStigNielsen's answer]
I'd just like to point out that you make Jeppe's approach generic as follows:
public class StructuralEqualityComparer<T>: IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
return StructuralComparisons.StructuralEqualityComparer.Equals(x, y);
}
public int GetHashCode(T obj)
{
return StructuralComparisons.StructuralEqualityComparer.GetHashCode(obj);
}
public static StructuralEqualityComparer<T> Default
{
get
{
StructuralEqualityComparer<T> comparer = _defaultComparer;
if (comparer == null)
{
comparer = new StructuralEqualityComparer<T>();
_defaultComparer = comparer;
}
return comparer;
}
}
private static StructuralEqualityComparer<T> _defaultComparer;
}
(From an original answer here: https://stackoverflow.com/a/5601068/106159)
Then you would declare the dictionary like this:
var yourDict = new Dictionary<double[], string>(new StructuralEqualityComparer<double[]>());
Note: It might be better to initialise _defaultComparer using Lazy<T>.
[EDIT]
It's possible that this might be faster; worth a try:
class DoubleArrayComparer: IEqualityComparer<double[]>
{
public bool Equals(double[] x, double[] y)
{
if (x == y)
return true;
if (x == null || y == null)
return false;
if (x.Length != y.Length)
return false;
for (int i = 0; i < x.Length; ++i)
if (x[i] != y[i])
return false;
return true;
}
public int GetHashCode(double[] data)
{
if (data == null)
return 0;
int result = 17;
foreach (var value in data)
result += result*23 + value.GetHashCode();
return result;
}
}
...
var yourDict = new Dictionary<double[], string>(new DoubleArrayComparer());
Ok this is what I found so far:
I input an entry (length 4 arrray) to the dictionary, and access it for 999999 times on my machine:
Dictionary<double[], string>(
new DoubleArrayStructuralEqualityComparer()); takes 1.75 seconds
Dictionary<Tuple<double...>,string> takes 0.85 seconds
The code below takes 0.1755285 seconds, which is the fastest now! (in line with the comment with Sergey.)
The fastest - The code of DoubleArrayComparer by Matthew Watson takes 0.15 seconds!
public class DoubleArray
{
private double[] d = null;
public DoubleArray(double[] d)
{
this.d = d;
}
public override bool Equals(object obj)
{
if (!(obj is DoubleArray)) return false;
DoubleArray dobj = (DoubleArray)obj;
if (dobj.d.Length != d.Length) return false;
for (int i = 0; i < d.Length; i++)
{
if (dobj.d[i] != d[i]) return false;
}
return true;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
for (int i = 0; i < d.Length;i++ )
{
hash = hash*23 + d[i].GetHashCode();
}
return hash;
}
}
}
I'm just wondering if there is a C# equivilent for this python code.
I want to store the names of methods in some sort of collection and call them later on. I have searched, but I really don't know what to look for.
For example in python I could do:
def add_one(x):
return x + 1
def double_it(x):
return x*2
maths_rules = [add_one, double_it]
def do_maths(maths_rules, x):
for func in maths_rules:
x = func(x)
return x
print do_maths(maths_rules, 9)
# >>> 20
This is a silly example, but you should get the idea.
You are looking for delegates.
A delegate is a type that defines a method signature. When you instantiate a delegate, you can associate its instance with any method with a compatible signature. You can invoke
(or call) the method through the delegate instance.
Your example in C#, using the Func<T, TResult> Delegate:
int add_one(int x) { return x + 1; }
int double_it(int x) { return x * 2; }
var maths_rules = new List<Func<int,int>> { add_one, double_it };
int do_maths(IEnumerable<Func<int,int>> maths_rules, int x)
{
foreach (var func in maths_rules)
{
x = func(x);
}
return x;
}
Console.WriteLine(do_maths(maths_rules, 9));
// prints "20"
Yes, you can use delegates. For this one use Func<int, int>.
like:
int addone(int x)
{
return x + 1;
}
and in main:
Func<int, int> myFunc = new Func<int, int>(addone);
myFunc(5); // to use it, you can pass it as you like
example on your code:
static int add_one(int x)
{
return x + 1;
}
static int double_it(int x)
{
return x * 2;
}
static int do_maths(List<Func<int, int>> math_rules, int x)
{
foreach(var func in math_rules)
x = func(x);
return x;
}
static void Main(string[] Args)
{
List<Func<int, int>> math_rules = new List<Func<int, int>>();
math_rules.Add(new Func<int, int>(add_one));
math_rules.Add(new Func<int, int>(double_it));
Console.WriteLine(do_maths(math_rules, 9)); // 20
}
or use lambdas as suggested in comment:
static int do_maths(List<Func<int, int>> math_rules, int x)
{
foreach(var func in math_rules)
x = func(x);
return x;
}
static void Main(string[] Args)
{
List<Func<int, int>> math_rules = new List<Func<int, int>>();
math_rules.Add(new Func<int, int>((x) => (x + 1)));
math_rules.Add(new Func<int, int>((x) => (x * 2)));
Console.WriteLine(do_maths(math_rules, 9)); // 20
}
Lets say I have the following code:
delegate int MyDel (int n); // my delegate
static int myMethod( MyDel lambda, int n) {
n *= n;
n = lambda(n);
return n; // returns modified n
}
This way, having different lambda expression I can tune the output of the Method.
myMethod ( x => x + 1, 5);
myMethod ( x => x - 1, 5);
Now, if I don't want to do any aritmethic in lambda expression, I could use:
myMethod ( x => x, 5); // and lambda will simply return x
My question is, is there a way to use the lambda expresion with 'params' optional properties? Maybe somehow embedding my delegate in array?
static int myMethod (int n, params MyDel lambda) {
Does this work?
EDIT
Sorry, was doing this with one eye, let me rephrase that.
static int myMethod (int n, params MyDel[] lambdas) {
Yes you can.
delegate int MyDelegate(int n);
static void MyMethod(int n, params MyDelegate[] handlers)
{
for (int i = 0; i < handlers.Length; i++)
{
if (handlers[i] == null)
throw new ArgumentNullException("handlers");
Console.WriteLine(handlers[i](n));
}
}
static void Main(string[] args)
{
MyMethod(1, x => x, x => x + 1);
Console.Read();
}
Output:
1
2