static private Get ( List |
||
left | List |
|
right | List |
|
Résultat |
private JObject ArrayDiff(JArray left, JArray right) { var result = JObject.Parse(@"{ ""_t"": ""a"" }"); int commonHead = 0; int commonTail = 0; if (JToken.DeepEquals(left, right)) { return(null); } // Find common head while (commonHead < left.Count && commonHead < right.Count && JToken.DeepEquals(left[commonHead], right[commonHead])) { commonHead++; } // Find common tail while (commonTail + commonHead < left.Count && commonTail + commonHead < right.Count && JToken.DeepEquals(left[left.Count - 1 - commonTail], right[right.Count - 1 - commonTail])) { commonTail++; } if (commonHead + commonTail == left.Count) { // Trivial case, a block (1 or more consecutive items) was added for (int index = commonHead; index < right.Count - commonTail; ++index) { result[$"{index}"] = new JArray(right[index]); } return(result); } if (commonHead + commonTail == right.Count) { // Trivial case, a block (1 or more consecutive items) was removed for (int index = commonHead; index < left.Count - commonTail; ++index) { result[$"_{index}"] = new JArray(left[index], 0, (int)DiffOperation.Deleted); } return(result); } // Complex Diff, find the LCS (Longest Common Subsequence) List <JToken> trimmedLeft = left.ToList().GetRange(commonHead, left.Count - commonTail - commonHead); List <JToken> trimmedRight = right.ToList().GetRange(commonHead, right.Count - commonTail - commonHead); Lcs lcs = Lcs.Get(trimmedLeft, trimmedRight); for (int index = commonHead; index < left.Count - commonTail; ++index) { if (lcs.Indices1.IndexOf(index - commonHead) < 0) { // Removed result[$"_{index}"] = new JArray(left[index], 0, (int)DiffOperation.Deleted); } } for (int index = commonHead; index < right.Count - commonTail; index++) { int indexRight = lcs.Indices2.IndexOf(index - commonHead); if (indexRight < 0) { // Added result[$"{index}"] = new JArray(right[index]); } else { int li = lcs.Indices1[indexRight] + commonHead; int ri = lcs.Indices2[indexRight] + commonHead; JToken diff = Diff(left[li], right[ri]); if (diff != null) { result[$"{index}"] = diff; } } } return(result); }
private JObject ArrayDiff(JArray left, JArray right) { var objectHash = this._options.ObjectHash; var itemMatch = new DefaultItemMatch(objectHash); var result = JObject.Parse(@"{ ""_t"": ""a"" }"); int commonHead = 0; int commonTail = 0; if (itemMatch.Match(left, right)) { return(null); } var childContext = new List <JToken>(); // Find common head while (commonHead < left.Count && commonHead < right.Count && itemMatch.Match(left[commonHead], right[commonHead])) { var index = commonHead; var child = Diff(left[index], right[index]); if (child != null) { result[$"{index}"] = child; } commonHead++; } // Find common tail while (commonTail + commonHead < left.Count && commonTail + commonHead < right.Count && itemMatch.Match(left[left.Count - 1 - commonTail], right[right.Count - 1 - commonTail])) { var index1 = left.Count - 1 - commonTail; var index2 = right.Count - 1 - commonTail; var child = Diff(left[index1], right[index2]); if (child != null) { result[$"{index2}"] = child; } commonTail++; } if (commonHead + commonTail == left.Count) { // Trivial case, a block (1 or more consecutive items) was added for (int index = commonHead; index < right.Count - commonTail; ++index) { result[$"{index}"] = new JArray(right[index]); } return(result); } if (commonHead + commonTail == right.Count) { // Trivial case, a block (1 or more consecutive items) was removed for (int index = commonHead; index < left.Count - commonTail; ++index) { if (result.ContainsKey(index.ToString())) { result.Remove(index.ToString()); } result[$"_{index}"] = new JArray(left[index], 0, (int)DiffOperation.Deleted); } return(result); } // Complex Diff, find the LCS (Longest Common Subsequence) List <JToken> trimmedLeft = left.ToList().GetRange(commonHead, left.Count - commonTail - commonHead); List <JToken> trimmedRight = right.ToList().GetRange(commonHead, right.Count - commonTail - commonHead); Lcs lcs = Lcs.Get(trimmedLeft, trimmedRight, itemMatch); for (int index = commonHead; index < left.Count - commonTail; ++index) { if (lcs.Indices1.IndexOf(index - commonHead) < 0) { // Removed if (result.ContainsKey(index.ToString())) { result.Remove(index.ToString()); } result[$"_{index}"] = new JArray(left[index], 0, (int)DiffOperation.Deleted); } } for (int index = commonHead; index < right.Count - commonTail; index++) { int indexRight = lcs.Indices2.IndexOf(index - commonHead); if (indexRight < 0) { // Added result[$"{index}"] = new JArray(right[index]); } else { int li = lcs.Indices1[indexRight] + commonHead; int ri = lcs.Indices2[indexRight] + commonHead; JToken diff = Diff(left[li], right[ri]); if (diff != null) { result[$"{index}"] = diff; } } } return(result); }
private List <Microsoft.AspNetCore.JsonPatch.Operations.Operation> ArrayDiff(JArray left, JArray right) { var result = new List <Microsoft.AspNetCore.JsonPatch.Operations.Operation>(); int commonHead = 0; int commonTail = 0; if (JToken.DeepEquals(left, right)) { return(null); } // Find common head while (commonHead < left.Count && commonHead < right.Count && JToken.DeepEquals(left[commonHead], right[commonHead])) { commonHead++; } // Find common tail while (commonTail + commonHead < left.Count && commonTail + commonHead < right.Count && JToken.DeepEquals(left[left.Count - 1 - commonTail], right[right.Count - 1 - commonTail])) { commonTail++; } if (commonHead + commonTail == left.Count) { // Trivial case, a block (1 or more consecutive items) was added for (int index = commonHead; index < right.Count - commonTail; ++index) { result.Add(new Microsoft.AspNetCore.JsonPatch.Operations.Operation("add", right.Path, null, right[index])); //result[$"{index}"] = new JArray(right[index]); } return(result); } if (commonHead + commonTail == right.Count) { // Trivial case, a block (1 or more consecutive items) was removed for (int index = commonHead; index < left.Count - commonTail; ++index) { result.Add(new Microsoft.AspNetCore.JsonPatch.Operations.Operation("remove", $"{right.Path}/{index}", null, null)); //result[$"_{index}"] = new JArray(left[index], 0, (int)DiffOperation.Deleted); } return(result); } // Complex Diff, find the LCS (Longest Common Subsequence) List <JToken> trimmedLeft = left.ToList().GetRange(commonHead, left.Count - commonTail - commonHead); List <JToken> trimmedRight = right.ToList().GetRange(commonHead, right.Count - commonTail - commonHead); Lcs lcs = Lcs.Get(trimmedLeft, trimmedRight); for (int index = commonHead; index < left.Count - commonTail; ++index) { if (lcs.Indices1.IndexOf(index - commonHead) < 0) { // Removed result.Add(new Microsoft.AspNetCore.JsonPatch.Operations.Operation("remove", $"{right.Path}/{index}", null, null)); //result[$"_{index}"] = new JArray(left[index], 0, (int)DiffOperation.Deleted); } } for (int index = commonHead; index < right.Count - commonTail; index++) { int indexRight = lcs.Indices2.IndexOf(index - commonHead); if (indexRight < 0) { // Added result.Add(new Microsoft.AspNetCore.JsonPatch.Operations.Operation("add", right.Path, null, right[index])); //result[$"{index}"] = new JArray(right[index]); } else { int li = lcs.Indices1[indexRight] + commonHead; int ri = lcs.Indices2[indexRight] + commonHead; var diff = Diff(left[li], right[ri]); if (diff != null) { foreach (var operation in diff) { result.Add(operation); } //result[$"{index}"] = diff; } } } return(result); }