5

Rubydiff-lcs在生成从一个序列到另一个序列所需的变更集方面做得很好,但是输出的格式让我有些困惑。我希望有一个更改列表,但输出始终是一个包含一个或两个更改列表的列表。拥有多个更改列表的含义/意图是什么?

考虑以下简单示例:

> Diff::LCS.diff('abc', 'a-c')
# => [[#<Diff::LCS::Change:0x01 @action="-", @position=1, @element="b">,
#      #<Diff::LCS::Change:0x02 @action="+", @position=1, @element="-">],
#     [#<Diff::LCS::Change:0x03 @action="-", @position=3, @element="">]]

忽略最后一个更改是空白的事实,为什么有两个更改列表而不是一个?

4

1 回答 1

3

如果有一个更好的例子,你可能会有更好的运气。如果你这样做:

Diff::LCS.diff('ab cd', 'a- c_')

然后输出看起来像这样(去除了噪音):

[
  [
    <@action="-", @position=1, @element="b">,
    <@action="+", @position=1, @element="-">
  ], [
    <@action="-", @position=4, @element="d">,
    <@action="+", @position=4, @element="_">
  ]
]

如果我们看Diff::LCS.diff('ab cd ef', 'a- c_ e+'),那么我们会得到三个内部数组而不是两个。

这可能有什么原因?diff 中有三个操作:

  1. 添加一个字符串。
  2. 删除字符串。
  3. 换一个字符串。

更改实际上只是删除和添加的组合,因此我们只剩下删除添加作为基本操作;这些与@action价值观非常吻合。但是,当人们查看差异时,我们希望将更改视为一个不同的操作,我们希望看到它b已经变成-,“删除b,添加-”版本是一个实现细节。

如果我们只有这样:

[
  <@action="-", @position=1, @element="b">,
  <@action="+", @position=1, @element="-">,
  <@action="-", @position=4, @element="d">,
  <@action="+", @position=4, @element="_">
]

然后你必须弄清楚哪些+/-对是真正的变化,哪些是单独的添加和删除。

因此,内部数组将两个基本操作(添加删除)映射到人类希望看到的三个操作(添加删除更改)。

您可能还想检查这些输出的结构:

  • Diff::LCS.diff('ab cd', 'a- x c_')
  • Diff::LCS.diff('ab', 'abx')
  • Diff::LCS.diff('ab', 'xbx')

我认为显式更改 @actionforDiff::LCS::Change会更好,但至少内部数组可以让您将单独的添加和删除分组到更高级别的编辑中。

于 2012-08-28T23:07:55.210 回答