I'm trying to find C#'s equivalent of Julia's map!() method, which is of void return type and takes a function, a destination and a collection on which the function acts.
The best thing that I could find is C#'s Enumerable.Select(), which takes the function as the third argument, and the collection as the first argument. However, it returns a new collection instead of modifying the one in the "destination". That resembles Julia's map() more.
There's nothing as standard like this, but you can easily add your own extension method to IEnumerable to add this functionality. For example:
public static void JuliaMap<TFrom, TTo>
(
this IEnumerable<TFrom> source,
IList<TTo> target,
Func<TFrom, TTo> selector
)
{
var next = 0;
foreach(var value in source)
{
var convertedValue = selector(value);
target[next] = convertedValue;
next++;
}
}
How you can say:
var numbers = new[]{1, 2, 3};
var target = new string[3];
numbers.JuliaMap(target, i => (i * 2).ToString());
NOTE: I've left out any error handling. For example, you'll want to make sure that the target list is long enough to take the inserted value.
Everything in LINQ is by design meant to never modify the underlying collection and to always create a new enumeration that is generally then used to instantiate a new collection.
You can write a helper function like this to achieve what you want:
public static void SelectToDestination<TSource, TResult>(
Func<TSource, TResult> selector,
IEnumerable<TSource> source,
IList<TResult> destination)
{
int i = 0;
foreach (var item in source.Select(selector))
{
destination[i] = item;
i++;
}
}
Usage looks like this:
var l1 = new List<int>() { 1, 2, 3, 4 };
var l2 = new List<int>() { 0, 0, 0, 0 };
SelectToDestination(x => x + 2, l1, l2);
foreach(var item in l2)
{
Console.Write(item + " ");
}
Results in: 3 4 5 6
Since we're using IList<T> in the method's signature, the destination can be an array too and it will work fine:
public static void Main(string[] args)
{
var l1 = new List<int>() { 1, 2, 3, 4 };
var l2 = new int[4];
SelectToDestination(x => x + 2, l1, l2);
foreach(var item in l2)
{
Console.Write(item + " ");
}
}
It takes advantage of the fact that until you call something like ToArray() or ToList(), LINQ hasn't yet instantiated a new collection, it's just iterating lazily over elements in the source collection. So just don't call ToArray() or ToList(), iterate over the resulting IEnumerable<TResult> and assign it to destination. Note that there are probably more perf friendly ways of doing this if that's a concern for you.
Just like Julia's map method, this will only work if the destination collection is at least as big.
Related
I want to write a function that processs two Lists of the same objects. The function does always the same thing:
Find the objects that are only in List2 but not in List1 -> Do something with them
Find the object that are in both Lists -> Do something different with them.
Now the point is, that I have List pairs holding different kind of objects to which I want to apply this exact process.
Example:
List<Foo1> L11, L12;
List<Foo2> L21, L22;
List<Foo3> L31, L32;
So how do I have to write the code, so that I do not have to repeat the code for each List type ?
Greetings and Thank you
I would prepare a method, like below:
static void Process<T>(IEnumerable<T> list1, IEnumerable<T> list2, Action<T> onlyIn2, Action<T> inBoth)
{
var hash = new HashSet<T>(list1);
foreach (var item2 in list2)
if (hash.Contains(item2))
inBoth(item2);
else
onlyIn2(item2);
}
You can then use it as follows:
var list1 = new List<int> {1, 2, 3, 4, 5};
var list2 = new List<int> {3, 4, 5, 6};
Process(list1, list2, a =>
{
Console.WriteLine("{0} only in 2", a);
}, a =>
{
Console.WriteLine("{0} in both", a);
});
Note that it uses standard comparison rules (for objects reference equality unless Equals is overrided or IEqualityComparer<TKey> is implemented).
LINQ already provides two methods which do this:
// get all members of L11 not present in L12
var except = L11.Except(L12).ToList();
// get members present in both lists
var intersect = L11.Intersect(L12).ToList();
These overloads will use the default comparer for the list element type, so since you want to compare custom classes, you will need to use the overload which accepts a custom IEqualityComparer<T>:
var comparer = new CustomComparer();
var except = L11.Except(L12, comparer).ToList();
var intersect = L11.Intersect(L12, comparer).ToList();
which you need to write yourself:
class CustomComparer : IEqualityComparer<SomeClass>
{
public bool Equals(SomeClass x, SomeClass y)
{
// return true if equal
}
public int GetHashCode(SomeClass obj)
{
// return a hash code for boj
}
}
Your can use the Except/Intersect Linq methods as follows:
void Process<T>(IList<T> list1, IList<T> list2, IEqualityComparer<T> comparer = null) {
//Find the objects that are only in List2 but not in List1
foreach(var item in list2.Except(list1, comparer)) {
// -> Do something with them
}
//Find the object that are in both Lists -> Do something different with them.
foreach(var item in list1.Intersect(list2, comparer)) {
// -> Do something different with them.
}
}
I have a Dictionary<T, IEnumerable<T>> that encodes a tree:
The keys represent all nodes of the tree and the values are the children of the corresponding nodes.
If a node does not have children, then its value is an empty enumerable.
E.g. the following mapping treeMap with T = int would be such a mapping that encodes a tree:
treeMap[1] = { 2, 3, 4 }
treeMap[2] = { 5, 6 }
treeMap[3] = { 7 }
treeMap[4] = { }
treeMap[5] = { }
treeMap[6] = { }
treeMap[7] = { 8 }
treeMap[8] = { }
I want to write a method UseFunctionOnTree(T node, Dictionary<T, IEnumerable<T>> treeMap, Function F) that apllies F to the given node, gets a new function newF from the old F and the node, and applies newF to all children.
This is as far as I got:
public class MapHelper<T>
{
public delegate Function Function (T element);
public static void UseFunctionOnTree(T node,
Dictionary<T, IEnumerable<T>> treeMap, Function F)
{
Function newF = F(node);
foreach (T child in treeMap[node])
UseFunctionOnTree (child, treeMap, newF);
}
}
Now my problem is that I don't know how to define such a Function.
I could define it like this:
public Function Useless(T element)
{
DoSthWith(element);
return Useless;
}
But I don't know how to define a function that returns something other than itself!
One of my use cases is the following:
I have a tree of type MyObject, where MyObject may look like this:
public class MyObject
{
public int index;
}
I take some int-valued offset, let's say firstOffset = 3. I want Function to add offset to node (i.e. to its index). Then I want to add an offset to all children of node, but this time the offset should be nextOffset = firstOffset + node.index.
Here is the pseudocode of what I want:
public Function AddOffset(T element)
{
int firstOffset;
// somehow make firstOffset = 3
int newOffset = firstOffset + element.index;
element.index = newOffset;
return AddOffset // but this time with the new offset
}
How do I do this? I feel like it might be solvable by some lambda statement...
Do I need more arguments? From the intuitive point of view, I don't.
E.g. we have
node1 with node1.index = 1 and
node2 with node2.index = 100.
We have F given as
"Add 3 to the index of your argument and store that number as n. Return a function that is like this one but adds n to the index of its argument."
From that we get that F(node1) will change node1.index to 3+1=4 and add 4 to its argument's index and consequently, (F(node1))(node2) will change node2.index to 4+100=104 and add 104 to it's argument's index. And ((F(node1))(node2))(node1) will change node1.index to 104+4=108 and add 108 to its argument's index, and so on.
Also I'd like to note that I do not always have the case of needing/changing one int parameter. It might be that I need several parameters, and their type can also vary on what concrete problem I want to solve. So it would be nice if I do not have to decide in advance how many (and of what type) parameters I need. It should all be contained in the Function itself.
Any hints are appreciated!
Just define an auxiliary function
public static Function MakeAddOffset(int offset)
{
return element => {
int newOffset = offset + element.index;
element.index = newOffset;
return MakeAddOffset(newOffset);
};
}
and then use MakeAddOffset(3) as the AddOffset function. (You can generalize this from AddOffset to any function F by defining a similar auxiliary function MakeF in the same manner as MakeAddOffset.)
There is a way to do this but I would not recommend it. Please have another thought about your algorithm and data structure in use. Personally, I would use a more object oriented approach, but let's try it.
The first abstraction would be to represent the data which use a manipulating with another generic type Q:
public class MapHelper<T, Q> {
// (insert the following code here)
}
At first, we need some more delegates to represent your mapping:
public delegate Q Getter(T element);
public delegate void Setter(T element, Q value);
public delegate Q Operation(Q left, Q right);
The Getter allows us to retrieve the index, the Setter can write new values and the Operation here is a simple addition. We need this functions when we are applying our mapping function:
public static void UseFunctionOnTree(T node,
Dictionary<T, IEnumerable<T>> treeMap, Function F, Getter g, Setter s) {
Function newF = F(node, g, s);
if (!treeMap.ContainsKey(node)) return;
foreach (T child in treeMap[node])
UseFunctionOnTree(child, treeMap, newF, g, s);
}
Now we can define GenericAddOffset which uses the declared delegates and a closure to define a new lambda function:
public static Function GenericAddOffset(T element, Getter g, Setter s, Operation o, Q left) {
Q newOffset = o(left, g(element));
s(element, newOffset);
return (T element1, Getter g1, Setter s1) => {
return GenericAddOffset(element1, g1, s1, o, newOffset);
};
}
This is the link you're missing: closures allow you to define function using variables from the outer scope.
At last, I defined a helper function:
public static void PrintTree(Dictionary<T, IEnumerable<T>> tree, Getter g) {
foreach (var value in tree) {
Console.Write("[" + g(value.Key).ToString() + "]: ");
foreach (var node in value.Value)
Console.Write(g(node).ToString() + " ");
Console.WriteLine();
Console.WriteLine();
}
}
Now, with:
using Helper = MapHelper<MyObject, int>;
we can write the following example program:
class Program {
public static void Main(string[] args) {
var tree = new Dictionary<MyObject, IEnumerable<MyObject>>();
Helper.Getter g = t => (int)t.index;
Helper.Setter s = (t, o) => { t.index = o; };
var root = new MyObject();
var node1 = new MyObject();
var node2 = new MyObject();
s(root, 1);
s(node1, 1);
s(node2, 100);
tree.Add(root, new[] { node1, node2 });
Helper.PrintTree(tree, g);
Helper.UseFunctionOnTree(root, tree,
(t, g1, s1) => { return Helper.GenericAddOffset(t, g1, s1, (x, y) => x + y, 3); }, g, s);
Helper.PrintTree(tree, g);
Console.ReadLine();
}
}
Output:
[1]: 1 100
[4]: 5 104
Given a bunch of lists, I need to iterate over them simultaneously. Suppose I have three of them: list1, list2, and list3.
What I found so far is the following:
foreach (var tuple in list1.Zip(list2, (first, second) => new { object1 = first, object2 = second })
.Zip(list3, (first, second) => new { object1 = first.object1, object2 = first.object2, object3 = second }))
{
//do stuff
}
This works fine and is quite readable, unless the number of lists is not big. I know how to extend it further to 4, 5,.... lists, but if I zip 10 of them, the code would be extremely long. Is there any possibility to refactor it? Or would I need other solution than Zip function?
With a help of a bit of code generation (think T4), one could produce up to 6 overloads (because Tuple is limited to 7 generic arguments) of something similar to:
public static class Iterate
{
public static IEnumerable<Tuple<T1, T2, T3>> Over<T1, T2, T3>(IEnumerable<T1> t1s, IEnumerable<T2> t2s, IEnumerable<T3> t3s)
{
using(var it1s = t1s.GetEnumerator())
using(var it2s = t2s.GetEnumerator())
using(var it3s = t3s.GetEnumerator())
{
while(it1s.MoveNext() && it2s.MoveNext() && it3s.MoveNext())
yield return Tuple.Create(it1s.Current, it2s.Current, it3s.Current);
}
}
}
With this Iterate class, iteration becomes very simple:
foreach(var t in Iterate.Over(
new[] { 1, 2, 3 },
new[] { "a", "b", "c" },
new[] { 1f, 2f, 3f }))
{
}
This can be futher generalized (with a total loss of type safety) to:
public static IEnumerable<object[]> Over(params IEnumerable[] enumerables)
Why not good old for loop?
int n = new int[] {
list1.Count,
list2.Count,
list3.Count,
// etc.
}.Min(); // if lists have different number of items
for (int i = 0; i < n; ++i) {
var item1 = list1[i]; // if you want an item
...
}
As far as I get it, the real problem is the unknown number of lists to iterate over. Another issue I see is that there is no guarantee that all the lists will have the same length... correct?
If the number of lists is unknown, tuples won't do it because they will go up to 8... and must be set at compile time...
In that case i would suggest that you, instead of mapping to a tuple, do it to a simple and very old structure: a matrix! The width will be the number of list (known at runtime) and the depth will be the longest list. You can iterate using a simple and well know for, have the compiler optimise memory and allocation... The code will be very readable not only by C# folks but for practically anyone who works with any kind of programming language...
Adding to #AntonGogolev's answer, on his last remark... if you don't care about type-safety and performance (for boxing-unboxing), you could implement an enumerator using object[]:
public static class Iterator
{
public static IEnumerable<object[]> Enumerate(params IEnumerable[] enumerables)
{
var list = new List<object>();
var enumerators = new List<IEnumerator>();
bool end = false;
foreach(var enu in enumerables)
{
enumerators.Add(enu.GetEnumerator());
}
while(!end)
{
list.Clear();
foreach(var enu in enumerators)
{
if(!enu.MoveNext()) { end = true; break; }
list.Add(enu.Current);
}
if(!end) yield return list.ToArray();
}
}
}
Warning: no effort whatsoever has been made to optimize this code and it has been written as it came through the fingers :-)
You can use it like:
var listA = new[] { 1, 2, 3 };
var listB = new[] { "a", "b", "c" };
var listC = new[] { 5f, 6f, 7f };
foreach(var n in Iterator.Enumerate(listA, listB, listC))
{
foreach(var obj in n)
{
Console.Write(obj.ToString() + ", ");
}
Console.WriteLine();
}
Fiddle here: https://dotnetfiddle.net/irTY8M
Disclaimer: this question is driven by my personal curiosity more than an actual need to accomplish something. So my example is going to be contrived.
Nevertheless I think it's an issue that might very well crop up.
Let's say we are using Zip to iterate over two sequences, invoking a void method that just throws an exception if one item of the couple is found to be different from the other (therefore discarding any return value). The point here is not that the method throws an exception, so much as it returns void.
In other words, we're kind of doing a ForEach over two collections (and by the way, I know what Eric Lippert thinks about ForEach, and fully agree with him and never use it).
Now, Zip wants a Func<TFirst, TSecond, TResult>, so of course passing something equivalent to Action<TFirst, TSecond> won't work.
My question is: is there an idiomatic way that is better than this (i.e. returning a dummy value)?
var collection1 = new List<int>() { ... };
var collection2 = new List<int>() { ... };
collection1.Zip(collection2, (first, second) =>
{
VoidMethodThatThrows(first, second);
return true;
});
Use Zip() to throw the items into an object, then do your foreach however way you choose (do a normal foreach loop please, not the bad ToList/ForEach combo).
var items = collection1.Zip(collection2, (x, y) => new { First = x, Second = y });
foreach (var item in items)
{
VoidMethodThatThrows(item.First, item.Second);
}
As of C# 7.0, improved tuple support and deconstruction makes it far more pleasing to work with.
var items = collection1.Zip(collection2, (x, y) => (x, y));
// or collection1.Zip(collection2, ValueTuple.Create);
foreach (var (first, second) in items)
{
VoidMethodThatThrows(first, second);
}
Furthermore, .NET Core and 5 adds an overload which automatically pairs the values into tuples so you don't have to do that mapping.
var items = collection1.Zip(collection2); // IEnumerable<(Type1, Type2)>
.NET 6 adds a third collection to the mix.
var items = collection1.Zip(collection2, collection3); // IEnumerable<(Type1, Type2, Type3)>
I often need to execute an action on each pair in two collections. The Zip method is not useful in this case.
This extension method ForPair can be used:
public static void ForPair<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second,
Action<TFirst, TSecond> action)
{
using (var enumFirst = first.GetEnumerator())
using (var enumSecond = second.GetEnumerator())
{
while (enumFirst.MoveNext() && enumSecond.MoveNext())
{
action(enumFirst.Current, enumSecond.Current);
}
}
}
So for your example, you could write:
var collection1 = new List<int>() { 1, 2 };
var collection2 = new List<int>() { 3, 4 };
collection1.ForPair(collection2, VoidMethodThatThrows);
what is fastest way to remove duplicate values from a list.
Assume List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 }; So I am interesting in use lambda to remove duplicate and returned : {1, 2, 3, 4, 5}. What is your suggestion?
The easiest way to get a new list would be:
List<long> unique = longs.Distinct().ToList();
Is that good enough for you, or do you need to mutate the existing list? The latter is significantly more long-winded.
Note that Distinct() isn't guaranteed to preserve the original order, but in the current implementation it will - and that's the most natural implementation. See my Edulinq blog post about Distinct() for more information.
If you don't need it to be a List<long>, you could just keep it as:
IEnumerable<long> unique = longs.Distinct();
At this point it will go through the de-duping each time you iterate over unique though. Whether that's good or not will depend on your requirements.
You can use this extension method for enumerables containing more complex types:
IEnumerable<Foo> distinctList = sourceList.DistinctBy(x => x.FooName);
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector)
{
var knownKeys = new HashSet<TKey>();
return source.Where(element => knownKeys.Add(keySelector(element)));
}
There is Distinct() method. it should works.
List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 };
var distinctList = longs.Distinct().ToList();
If you want to stick with the original List instead of creating a new one, you can something similar to what the Distinct() extension method does internally, i.e. use a HashSet to check for uniqueness:
HashSet<long> set = new HashSet<long>(longs.Count);
longs.RemoveAll(x => !set.Add(x));
The List class provides this convenient RemoveAll(predicate) method that drops all elements not satisfying the condition specified by the predicate. The predicate is a delegate taking a parameter of the list's element type and returning a bool value. The HashSet's Add() method returns true only if the set doesn't contain the item yet. Thus by removing any items from the list that can't be added to the set you effectively remove all duplicates.
List<long> distinctlongs = longs.Distinct().OrderBy(x => x).ToList();
A simple intuitive implementation
public static List<PointF> RemoveDuplicates(List<PointF> listPoints)
{
List<PointF> result = new List<PointF>();
for (int i = 0; i < listPoints.Count; i++)
{
if (!result.Contains(listPoints[i]))
result.Add(listPoints[i]);
}
return result;
}
In-place:
public static void DistinctValues<T>(List<T> list)
{
list.Sort();
int src = 0;
int dst = 0;
while (src < list.Count)
{
var val = list[src];
list[dst] = val;
++dst;
while (++src < list.Count && list[src].Equals(val)) ;
}
if (dst < list.Count)
{
list.RemoveRange(dst, list.Count - dst);
}
}