示例#1
0
        internal static IEnumerable <Operation> CalculatePatch(JToken left, JToken right, bool useIdToDetermineEquality,
                                                               string path = "")
        {
            if (left.Type != right.Type)
            {
                yield return(JsonDiffer.Replace(path, "", right));

                yield break;
            }

            if (left.Type == JTokenType.Array)
            {
                Operation prev = null;
                foreach (var operation in ProcessArray(left, right, path, useIdToDetermineEquality))
                {
                    var add = operation as AddOperation;
                    if (prev is RemoveOperation prevRemove && add != null && add.Path == prevRemove.Path)
                    {
                        yield return(Replace(add.Path, "", add.Value));

                        prev = null;
                    }
                    else
                    {
                        if (prev != null)
                        {
                            yield return(prev);
                        }
                        prev = operation;
                    }
                }
        internal static IEnumerable <Operation> CalculatePatch(JToken left, JToken right, bool useIdToDetermineEquality,
                                                               string path = "")
        {
            if (left.Type != right.Type)
            {
                yield return(JsonDiffer.Replace(path, "", right));

                yield break;
            }

            if (left.Type == JTokenType.Array)
            {
                Operation prev = null;
                foreach (var operation in ProcessArray(left, right, path, useIdToDetermineEquality))
                {
                    var prevRemove = prev as RemoveOperation;
                    var add        = operation as AddOperation;
                    if (prevRemove != null && add != null && add.Path == prevRemove.Path)
                    {
                        yield return(Replace(add.Path, "", add.Value));

                        prev = null;
                    }
                    else
                    {
                        if (prev != null)
                        {
                            yield return(prev);
                        }
                        prev = operation;
                    }
                }
                if (prev != null)
                {
                    yield return(prev);
                }
            }
            else if (left.Type == JTokenType.Object)
            {
                var lprops = ((IDictionary <string, JToken>)left).OrderBy(p => p.Key);
                var rprops = ((IDictionary <string, JToken>)right).OrderBy(p => p.Key);

                foreach (var removed in lprops.Except(rprops, MatchesKey.Instance))
                {
                    yield return(JsonDiffer.Remove(path, removed.Key));
                }

                foreach (var added in rprops.Except(lprops, MatchesKey.Instance))
                {
                    yield return(JsonDiffer.Add(path, added.Key, added.Value));
                }

                var matchedKeys = lprops.Select(x => x.Key).Intersect(rprops.Select(y => y.Key));
                var zipped      = matchedKeys.Select(k => new { key = k, left = left[k], right = right[k] });

                foreach (var match in zipped)
                {
                    string newPath = path + "/" + match.key;
                    foreach (var patch in CalculatePatch(match.left, match.right, useIdToDetermineEquality, newPath))
                    {
                        yield return(patch);
                    }
                }
                yield break;
            }
            else
            {
                // Two values, same type, not JObject so no properties

                if (left.ToString() == right.ToString())
                {
                    yield break;
                }
                else
                {
                    yield return(JsonDiffer.Replace(path, "", right));
                }
            }
        }