当前位置:   article > 正文

js文本比较(json数据比较)

js文本比较(json数据比较)

最近有个需求要求比较json数据,当然有最简单的方法,循环每个键来比值,但是我偏不!因为正好想趁这个机会写一个文本比较的工具(类似git自带的比较),我搜了一下网络只找到一个LD算法似乎可以用,自己写了个demo效率一般把,而且感觉好复杂太高深。所以还是以我的理解写了一个比较工具。

水平有限所以我不会写很高深的东西,所以尽量往简单的地方靠。基本概念,就是先把文本分段(比如5行一段),然后在这5行里找一个连续最多的行做基准(文本差异度>60的认为是新增行,其他的是编辑行),向下连续查找。简单的说就是尽量把能连续对上的作为基准,一路往下对。

这里提一下,如果希望比对的更精确,可以把findLen设置的大一点,比如设置成left或right里比较大的行数,这样比对起来会避免一些问题,如:当中隔了很多行(>findLen)才是正确的行,导致检索默认5行没找到,就认为是新增行了。当然这样每条比的数量就多了也就慢了自己把握。

  1. function compare(){
  2. this.findLen = 5, // 查块大小,如果你希望更准确可以把这个值改大一点比如50行
  3. this.jsonSort = function (obj) {
  4. let names = [];
  5. let newObj = {};
  6. if (Array.isArray(obj)) {
  7. let list = [];
  8. for (let i=0;i<obj.length;i++) {
  9. list.push(this.jsonSort(obj[i]));
  10. }
  11. list.sort();
  12. return list;
  13. } else {
  14. for (let o in obj) {
  15. names.push(o);
  16. }
  17. names.sort();
  18. for (let i=0;i<names.length;i++) {
  19. let n = names[i];
  20. if ("function" != typeof obj[n]) {
  21. if ("object" == typeof obj[n]) {
  22. if (obj[n]) {
  23. newObj[n] = this.jsonSort(obj[n]);
  24. }
  25. } else {
  26. newObj[n] = obj[n];
  27. }
  28. }
  29. }
  30. }
  31. return newObj;
  32. },
  33. this.json2Lines = function (obj) {
  34. let jsonVal = JSON.stringify(obj, null, '\t');
  35. let lines = [];
  36. let lineStr = "";
  37. console.log(jsonVal);
  38. for (let i=0;i<jsonVal.length; i++) {
  39. if ('\t' == jsonVal.charAt(i) || '\n' == jsonVal.charAt(i)) {
  40. let s = lineStr.trim();
  41. if (s.length > 0) {
  42. lines.push(lineStr.trim());
  43. }
  44. lineStr = "";
  45. } else {
  46. lineStr += jsonVal.charAt(i);
  47. }
  48. }
  49. lines.push(lineStr);
  50. return lines;
  51. },
  52. this.difference = function (leftStr, rightStr) {
  53. let count = 0, tmpCount = 0;
  54. for (let i=0;i<leftStr.length && i < rightStr.length;i++) {
  55. if (leftStr.charAt(i) == rightStr.charAt(i)) {
  56. tmpCount++;
  57. } else {
  58. count += tmpCount;
  59. tmpCount = 0;
  60. }
  61. }
  62. if (tmpCount > 0) {
  63. count+=tmpCount;
  64. }
  65. return count / Math.max(leftStr.length, rightStr.length) * 100;
  66. },
  67. this.compareFind = function (index, start, left, right) {
  68. let val = {
  69. right: start,
  70. series: 0,
  71. find: false
  72. };
  73. if (index < left.length && start < right.length) {
  74. let score = this.difference(left[index], right[start]);
  75. if (score > 60) {
  76. let rtn = this.compareFind(index + 1, start + 1, left ,right);
  77. val.find = true;
  78. val.series += rtn.series + 1;
  79. }
  80. }
  81. return val;
  82. },
  83. this.compareNext = function (s1, s2, left, right, result) {
  84. let diff = {
  85. left: 0,
  86. series: 0,
  87. right: 0,
  88. find: false
  89. };
  90. for (let i=s1; i - s1 < this.findLen && i< left.length; i++) {
  91. let len = this.compareFind(i, s2, left, right);
  92. if (diff.series < len.series) {
  93. diff.left = i;
  94. diff.series = len.series;
  95. diff.right = len.right;
  96. }
  97. }
  98. if (diff.series > 0) {
  99. for (let i=s1;i<diff.left;i++) {
  100. result[i] = "<span style='background-color: pink'>" + left[i] + "</span>"; // 标记新增的部分
  101. }
  102. let r = diff.right;
  103. for (let i=diff.left; i<diff.left + diff.series;i++) {
  104. let score = this.difference(left[i], right[r++]);
  105. if (score < 100) {
  106. result[i] = "<span style='background-color: yellow'>" + left[i] + "</span>"; // 标记修改的部分
  107. } else {
  108. result[i] = left[i]; // 相同的部分
  109. }
  110. }
  111. diff.find = true;
  112. } else {
  113. // result.push("<span style='background-color: pink'>" + left[s1] + "</span>"); // 标记新增的部分
  114. if (s2 + 1 < right.length) {
  115. let f = this.compareNext(s1, s2 + 1, left, right, result);
  116. return {
  117. series: f.series,
  118. left: f.left,
  119. right: f.right,
  120. find: f.find
  121. }
  122. } else {
  123. diff.left = s1 + 1;
  124. diff.right = s2;
  125. }
  126. }
  127. return {
  128. series: diff.series,
  129. left: diff.left + diff.series,
  130. right: diff.right + diff.series,
  131. find: diff.find
  132. };
  133. },
  134. this.compareJson = function (left, right) {
  135. let result = [];
  136. let liftLine = this.json2Lines(left);
  137. let rightLine = this.json2Lines(right);
  138. let lIndex = 0, rIndex = 0;
  139. while (lIndex < liftLine.length) {
  140. let diff = this.compareNext(lIndex, rIndex, liftLine, rightLine, result);
  141. if (!diff.find) {
  142. result[lIndex] = "<span style='background-color: pink'>" + left[lIndex] + "</span>"; // 标记新增的部分
  143. }
  144. lIndex = diff.left;
  145. rIndex = diff.right;
  146. // break;
  147. }
  148. return result;
  149. },
  150. this.jsonToCompare = function (left, right) {
  151. try {
  152. //json对象排序
  153. let l = this.jsonSort(JSON.parse(left));
  154. let r = this.jsonSort(JSON.parse(right));
  155. let res = this.compareJson(l, r);
  156. return res.join(" ");
  157. } catch (e) {}
  158. return left;
  159. }
  160. }
  1. //调用例子
  2. let json1= {
  3. v1: "abc",
  4. v2: "ccc",
  5. v3: "ddd",
  6. v4: "555"
  7. }, json2= {
  8. v1: "abc",
  9. v2: "ccc",
  10. v3: "eee"
  11. }
  12. let cp = new compare();
  13. cp.jsonToCompare(json1, json2);

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/272910
推荐阅读