/// <summary> /// Merges <see cref="P:source"/> into <see cref="P:destination"/> by first creating a diff /// and then changing <see cref="P:source"/> in place by calling Insert and RemoveAt. /// The <see cref="P:create"/> function is used to create new <see cref="T:TSource"/> items /// from <see cref="T:TDestination"/> items. /// The <see cref="P:update"/> action is called whenever items already match between the /// source and destination. /// The <see cref="P:delete"/> action is called whenever items are removed from the source list. /// </summary> /// <returns>The diff used to merge.</returns> /// <param name="source">Source item list</param> /// <param name="destination">Destination item sequence</param> /// <param name="match">Predicate used to match source and destination items</param> /// <param name="create">Function used to create new source items from destination items when they need to be inserted</param> /// <param name="update">Action invoked when source and destination items match</param> /// <param name="delete">Action invoked when source items are removed</param> /// <typeparam name="TSource">The type of items in the source list</typeparam> /// <typeparam name="TDestination">The type of items in the destination sequence</typeparam> public static ListDiff <TSource, TDestination> MergeInto <TSource, TDestination> (this IList <TSource> source, IEnumerable <TDestination> destination, Func <TSource, TDestination, bool> match, Func <TDestination, TSource> create, Action <TSource, TDestination> update, Action <TSource> delete) { var diff = new ListDiff <TSource, TDestination> (source, destination, match); var p = 0; foreach (var a in diff.Actions) { if (a.ActionType == ListDiffActionType.Add) { source.Insert(p, create(a.DestinationItem)); p++; } else if (a.ActionType == ListDiffActionType.Remove) { delete(a.SourceItem); source.RemoveAt(p); } else { update(a.SourceItem, a.DestinationItem); p++; } } return(diff); }
/// <summary> /// Merges <see cref="P:source"/> into <see cref="P:destination"/> by first creating a diff /// and then changing <see cref="P:source"/> in place by calling Insert and RemoveAt. /// </summary> /// <returns>The diff used to merge.</returns> /// <param name="source">Source item list</param> /// <param name="destination">Destination item sequence</param> /// <param name="match">Predicate used to match source and destination items</param> /// <typeparam name="T">The type of items in the list</typeparam> public static ListDiff <T, T> MergeInto <T> (this IList <T> source, IEnumerable <T> destination, Func <T, T, bool> match) { var diff = new ListDiff <T, T> (source, destination, match); var p = 0; foreach (var a in diff.Actions) { if (a.ActionType == ListDiffActionType.Add) { source.Insert(p, a.DestinationItem); p++; } else if (a.ActionType == ListDiffActionType.Remove) { source.RemoveAt(p); } else { p++; } } return(diff); }