Created
May 10, 2016 14:52
-
-
Save g4s8/9a63d637e4e5e36207da7dbcf287eb9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace ConsoleApplication10 { | |
public static class CollectionsMerge { | |
private interface IMergeNode<T> { | |
T Resolve(Func<T, T, T> onConflict); | |
} | |
private sealed class NodeConflicted<T> : IMergeNode<T> { | |
private readonly T _left; | |
private readonly T _right; | |
public NodeConflicted(T left, T right) { | |
_left = left; | |
_right = right; | |
} | |
public T Resolve(Func<T, T, T> onConflict) { | |
return onConflict(_left, _right); | |
} | |
} | |
private sealed class NodeSimple<T> : IMergeNode<T> { | |
private readonly T _single; | |
public NodeSimple(T single) { | |
_single = single; | |
} | |
public T Resolve(Func<T, T, T> onConflict) { | |
return _single; | |
} | |
} | |
public static IEnumerable<T> MergeWith<T, TKey>( | |
this IEnumerable<T> self, | |
IEnumerable<T> other, | |
Func<T, TKey> uniqueKeySelector, | |
Func<T, T, T> onConflict | |
) where TKey : IEquatable<TKey> { | |
var d1 = self.ToDictionary(i => uniqueKeySelector(i), i => i); | |
var d2 = other.ToDictionary(i => uniqueKeySelector(i), i => i); | |
List<IMergeNode<T>> merge = new List<IMergeNode<T>>(); | |
foreach (var entry in d1) { | |
T same; | |
if (d2.TryGetValue(entry.Key, out same)) { | |
merge.Add(new NodeConflicted<T>(entry.Value, same)); | |
d2.Remove(entry.Key); | |
} else { | |
merge.Add(new NodeSimple<T>(entry.Value)); | |
} | |
} | |
foreach (var entry in d2) { | |
merge.Add(new NodeSimple<T>(entry.Value)); | |
} | |
return merge.Select(node => node.Resolve(onConflict)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment