The desired behavior would be:
[TestMethod]
public void Compare_Value_Identity()
{
var source = new[] { 1, 2 };
var modified = new[] { 2, 3 };
var (inserted, deleted) = source.Compare(modified);
CollectionAssert.AreEqual(new[] { 3 }, inserted.ToArray());
CollectionAssert.AreEqual(new[] { 1 }, deleted.ToArray());
}
And:
[TestMethod]
public void Compare_Id_Identity()
{
var source = new[] { (1, "A"), (2, "B"), (3, "C") };
var modified = new[] { (2, "B"), (3, "D"), (4, "E") };
var (inserted, updated, deleted) = source.Compare(modified, x => x.Item1);
CollectionAssert.AreEqual(new[] { (4, "E") }, inserted.ToArray());
CollectionAssert.AreEqual(new[] { (3, "D") }, updated.ToArray());
CollectionAssert.AreEqual(new[] { (1, "A") }, deleted.ToArray());
}
Library code is:
public static class SequenceChange
{
public static (IEnumerable<T> Inserted, IEnumerable<T> Deleted) Compare<T>(
this IEnumerable<T> source, IEnumerable<T> modified) =>
source.Compare(modified, EqualityComparer<T>.Default);
public static (IEnumerable<T> Inserted, IEnumerable<T> Deleted) Compare<T>(
this IEnumerable<T> source, IEnumerable<T> modified, IEqualityComparer<T> comparer) =>
(modified.Except(source, comparer), source.Except(modified, comparer));
public static (IEnumerable<T> Inserted, IEnumerable<T> Updated, IEnumerable<T> Deleted) Compare<T, TKey>(
this IEnumerable<T> source, IEnumerable<T> modified, Func<T, TKey> keySelector) =>
source.Compare(modified, keySelector, EqualityComparer<T>.Default);
public static (IEnumerable<T> Inserted, IEnumerable<T> Updated, IEnumerable<T> Deleted) Compare<T, TKey>(
this IEnumerable<T> source, IEnumerable<T> modified, Func<T, TKey> keySelector, IEqualityComparer<T> comparer) =>
(modified.ExceptBy(source, keySelector),
from s in source
join m in modified on keySelector(s) equals keySelector(m)
where !comparer.Equals(s, m)
select m,
source.ExceptBy(modified, keySelector));
}
ExceptBy
from ? Some library ? \$\endgroup\${ (1, "A"), (1, "F") }
and{ (1, "B"), (1, "D"), (1, "E") }
? For me that is not clear ... Code returns confusing results with 6 updated items (!) which is more than the total number of both sequences \$\endgroup\$keySelector
\$\endgroup\$