gpt4 book ai didi

ruby - 无法理解以下代码的作用

转载 作者:数据小太阳 更新时间:2023-10-29 08:39:56 24 4
gpt4 key购买 nike

有人可以向我解释下面的代码在做什么吗? beforeafter 是哈希值。

def differences(before, after)
before.diff(after).keys.sort.inject([]) do |diffs, k|
diff = { :attribute => k, :before => before[k], :after => after[k] }
diffs << diff; diffs
end
end

它来自 papertrail differ gem。

最佳答案

毫无疑问,这是密集的代码。因此,正如您所说,beforeafter 是作为参数传递给方法的散列(类似?)对象。调用 before.diff(after) 返回另一个散列,然后立即调用 .keys。这将返回 diff 返回的散列中的所有键。键作为数组返回,然后立即排序。

然后我们进入最复杂/最密集的部分。在排序的键数组上使用 inject,该方法构建一个数组(在 inject block 中称为 diffs),这将是返回值inject 方法。

该数组由差异记录组成。每条记录都是一个散列 - 通过从 before.diff(after) 返回值的已排序键数组中取出一个键来构建。这些散列存储被差异化的属性,它在前哈希中的样子以及在后哈希中的样子。

因此,简而言之,该方法获取两个哈希值之间的一堆差异,并将它们收集到一个哈希值数组中。该哈希数组是该方法的最终返回值。

注意:inject 可以而且通常比这简单得多。通常它用于通过一遍又一遍地应用一个操作并将结果存储在累加器中来简单地将一组值减少为一个结果。您可能从其他语言中将 inject 理解为 reducereduce 是 Ruby 中 inject 的别名。下面是一个更简单的 inject 示例:

[1,2,3,4].inject(0) do |sum, number|
sum + number
end
# => 10

0 是累加器——初始值。在 |sum, number| 对中,sum 将是累加器,number 将是数组中的每个数字,一个接一个。 inject做的是0加1,存入sum用于下一轮,sum加2,存入sum 再次等等。累加器 sum 的单个最终值将是返回值。这里是 10。您的示例中增加的复杂性是累加器与 block 内的值在种类上不同。这种情况不太常见,但还不错,也不错。 (编辑:Andrew Marshall 提出了好的观点,但也可能是坏的。请参阅他对原始问题的评论。@tokland 指出,inject 这里只是一个非常 map 的过于复杂的替代方案。它不好的。)有关注入(inject)的更多示例,请参阅我在您的问题的评论中链接到的文章。

编辑:正如@tokland 在一些评论中指出的那样,代码似乎只需要一个简单的map。那样读起来会容易得多。

def differences(before, after)
before.diff(after).keys.sort.map do |k|
{ :attribute => k, :before => before[k], :after => after[k] }
end
end

我过于专注于解释代码的作用。我什至没有想到如何简化它。

关于ruby - 无法理解以下代码的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11129505/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com