- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
考虑这段代码:
h = Hash.new(0) # New hash pairs will by default have 0 as values
h[1] += 1 #=> {1=>1}
h[2] += 2 #=> {2=>2}
没关系,但是:
h = Hash.new([]) # Empty array as default value
h[1] <<= 1 #=> {1=>[1]} ← Ok
h[2] <<= 2 #=> {1=>[1,2], 2=>[1,2]} ← Why did `1` change?
h[3] << 3 #=> {1=>[1,2,3], 2=>[1,2,3]} ← Where is `3`?
此时我希望散列为:
{1=>[1], 2=>[2], 3=>[3]}
但远非如此。发生了什么,我怎样才能得到我期望的行为?
最佳答案
首先,请注意,此行为适用于随后发生变化的任何默认值(例如哈希和字符串),而不仅仅是数组。它也同样适用于 Array.new(3, [])
中的填充元素。 .
TL;DR:使用 Hash.new { |h, k| h[k] = [] }
如果您想要最惯用的解决方案并且不在乎为什么。
Hash.new([])
不工作让我们更深入地了解为什么 Hash.new([])
不起作用:
h = Hash.new([])
h[0] << 'a' #=> ["a"]
h[1] << 'b' #=> ["a", "b"]
h[1] #=> ["a", "b"]
h[0].object_id == h[1].object_id #=> true
h #=> {}
我们可以看到我们的默认对象正在被重用和变异(这是因为它作为唯一的默认值传递,哈希无法获得新的默认值),但为什么没有数组中的键或值,尽管 h[1]
仍然给我们一个值(value)?这是一个提示:
h[42] #=> ["a", "b"]
每个[]
返回的数组call 只是默认值,我们一直在改变它,所以现在包含我们的新值。自 <<
不赋值给散列(在 Ruby 中没有 =
就永远不会赋值 †),我们从来没有把任何东西放入我们的实际散列中。相反,我们必须使用 <<=
(它是 <<
,因为 +=
是 +
):
h[2] <<= 'c' #=> ["a", "b", "c"]
h #=> {2=>["a", "b", "c"]}
这等同于:
h[2] = (h[2] << 'c')
Hash.new { [] }
不工作使用 Hash.new { [] }
解决了重用和改变原始默认值的问题(因为每次调用给定的 block ,返回一个新数组),但不是赋值问题:
h = Hash.new { [] }
h[0] << 'a' #=> ["a"]
h[1] <<= 'b' #=> ["b"]
h #=> {1=>["b"]}
如果我们记得始终使用 <<=
, 然后 Hash.new { [] }
是一个可行的解决方案,但它有点古怪且不合常理(我从未见过 <<=
在野外使用过)。如果<<
,它也容易出现细微的错误被无意中使用。
documentation for Hash.new
状态(强调我自己的):
If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.
因此,如果我们希望使用 <<
,我们必须将默认值存储在 block 内的散列中。而不是 <<=
:
h = Hash.new { |h, k| h[k] = [] }
h[0] << 'a' #=> ["a"]
h[1] << 'b' #=> ["b"]
h #=> {0=>["a"], 1=>["b"]}
这有效地将分配从我们的个人调用(将使用 <<=
)移动到传递给 Hash.new
的 block ,消除使用时意外行为的负担 <<
.
请注意,此方法与其他方法之间存在一个功能差异:这种方法在读取时分配默认值(因为分配总是在 block 内发生)。例如:
h1 = Hash.new { |h, k| h[k] = [] }
h1[:x]
h1 #=> {:x=>[]}
h2 = Hash.new { [] }
h2[:x]
h2 #=> {}
你可能想知道为什么 Hash.new([])
在 Hash.new(0)
时不起作用工作得很好。关键是 Ruby 中的数值是不可变的,所以我们自然永远不会就地改变它们。如果我们将默认值视为不可变的,我们可以使用 Hash.new([])
也很好:
h = Hash.new([].freeze)
h[0] += ['a'] #=> ["a"]
h[1] += ['b'] #=> ["b"]
h[2] #=> []
h #=> {0=>["a"], 1=>["b"]}
但是,请注意 ([].freeze + [].freeze).frozen? == false
.因此,如果要确保始终保持不变性,则必须注意重新卡住新对象。
在所有方式中,我个人更喜欢“不可变方式”——不可变性通常会使事情的推理变得更加简单。毕竟,这是唯一不可能出现隐藏或微妙的意外行为的方法。然而,最常见和惯用的方式是“可变方式”。
最后,散列默认值的这种行为在 Ruby Koans 中有所说明。 .
† 这不是严格意义上的,像 instance_variable_set
这样的方法绕过这个,但是它们必须存在用于元编程,因为 =
中的左值不能是动态的。
关于ruby - 使用哈希默认值时出现奇怪的意外行为(消失/更改值),例如哈希.new([]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2698460/
我使用 vanilla JS 通过 AJAX 向数据库发送请求。数据写入数据库没有问题。在刷新页面之前,我看不到被放入数据库中的内容。当我删除内容时也会发生同样的情况,我必须刷新才能看到内容消失了。
抱歉,这篇文章很长,我试图提供所有信息并解释我已经尝试过的内容。 问题: 我将经典的 Phoenix View 放入实时 View 中。虽然一切看起来都很好,但 echart 一完成绘制就消失了。好像
搜索了一下,没有找到我要找的东西。我有两个按钮,单击一次即可拉出两个不同的选择框,第二次单击它们就会消失。但是,我希望选择框 1 在单击按钮 2 时消失,反之亦然:选择框 2 将在单击按钮 1 时消失
我正在尝试使用自动布局使用“浮动”标题构建滚动视图。更确切地说,我正在尝试建立包含几列的日历视图。这些列中的每个列都应具有自己的标题,该标题应浮动在顶部,而该列可以垂直滚动到其下方。 如果一切正常,则
我正在尝试模仿星星背景。 星星是在加载时创建并随机散布在整个网站上的。到目前为止我已经调整了一些代码。 var star="•"; var numStars=100; for(var x=1;x•";
我查遍了整个网络,但找不到解决方案。我对 jQuery 也很陌生。 我的案例: 我有一个导航栏,其中的每个链接都会激活/触发一个megamenu(每个链接都有自己的megamenu)。 我需要什么:
我有一个可扩展的 ListView ,当我点击一行时,它会触发 onChildClick 或 onGroupClick,具体取决于我点击的是子项还是组。 如果我在 xml 布局文件中添加可点击的内容(
在我的程序中,我有一个 NSMutableData 变量,用于收集来自 http://www.nhara.org/scored_races-2013.htm 的信息。 .大约第三次从网站获取信息后,当
我一直在完美地使用 Genymotion,但是从最近几天开始我的 Genymotion 并打开它的 GPS 开始,我的 Genymotion 突然消失了。但是我的 eclipse 显示 Genymot
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and t
所以我的 Item::return_all() 有问题,因为我在 main.cpp 中调用它。早些时候我在 read_file() 和 for (auto data : example_item) 中
所有 UITableCells 在 UITableView 中滚动和触摸时消失。一切都以编程方式完成,我使用标准的 UITableViewCell 类。 我在某处读到包含我的单元格数据的数组可能被清空
我对 Swift 还很陌生。我的问题是我的 UICollectionView 正在消失。在 Xcode 中,它显示一切就绪,但当我在模拟器或设备上启动时,它消失了,只剩下导航栏和标签栏。 有谁知道是什
这是 this one的续题。较早的问题是在复选框上。但是后来我根据要求把check box改成了radio buttons。 现在我需要显示子单选按钮并在母单选按钮处于事件状态时更改背景颜色。一旦它
我用 JS 写了一个简单的脚本。当我将它放入 html 文档(在 body 标签的底部)时,它工作正常。当我尝试将它放入外部文档并链接它时,脚本运行但 canvas 元素消失(刚刚检查:当我将脚本放在
我正在尝试创建一个带有固定元素的滚动页面,当用户向下滚动页面时,该元素“始终”可见。例如,带有道路背景的汽车图像。因此,当用户向下滚动页面时,汽车看起来就像在路上行驶。虽然汽车出现在道路的顶部,但它必
这个问题在这里已经有了答案: How can I change CSS display none or block property using jQuery? (15 个答案) 关闭 4 年前。
我在市场上有一个支持小部件的应用程序。我对应用程序进行了一些重大更改,重新设计了很多内部结构,替换/重命名 Activity 等。其他更改包括从不同的共享首选项键获取小部件配置数据,尽管我已经编写了转
我有一个 fragment alertsfragment.java,它有一个 GridView 布局,当我打开它时,它工作正常,但是当我在其他选项卡之间滑动时,它就消失了。为了解释更多,我有一个 Ac
我是一名优秀的程序员,十分优秀!