Arrays 如何将哈希插入数组

Arrays 如何将哈希插入数组,arrays,ruby,Arrays,Ruby,我有一个文件file.txt,它有一个数组,其中包括散列: [{:name "Muhammad"},{:name "Mahmoud"}] 我试图通过以下方式阅读: $list = File.readlines('file.txt') 然后我将散列添加到数组中: $list << hash $list << hash $list << hash 当我用以下内容读取文件时: $list = File.read('file.txt') 然后将hast[s

我有一个文件
file.txt
,它有一个数组,其中包括散列:

[{:name "Muhammad"},{:name "Mahmoud"}]
我试图通过以下方式阅读:

$list = File.readlines('file.txt')
然后我将
散列
添加到数组中:

$list << hash
$list << hash
$list << hash
当我用以下内容读取文件时:

$list = File.read('file.txt')
然后将
hast
[sic]添加到数组中:

$list << hash
$list << hash
$list << hash
它给出了以下错误:

can't convert Hash into String (TypeError)

如何向数组中添加散列?

您误解了
读取行
读取
的作用以及文件的内容。让我们从这些事情开始:

  • 文件不包含数组或散列-它们包含可能可以解析为数组或散列的文本
  • File.read
    将文件内容读入字符串
  • File.readlines
    将文件内容读入包含字符串的数组,其中每个字符串都是文件的一行。它(大致)相当于
    File.read('filename.txt').split(“\n”)
  • 因此,考虑您的文件,其中包含(更正为有效的Ruby语法)

    尽管在您看来它像一个包含哈希的数组,但括号没有语义含义。让我们读一下:

    > data = File.read('file.txt')
     => "[{name: \"Muhammad\"},{name: \"Mahmoud\"}]\n"
    
    请注意以下几点:

    • 数据周围有引号-它是一个字符串
    • 文件中的引号(
      “Muhammad”
      )将被转义
    • 字符串末尾有一个
      \n
      ,表示换行符
    我们可以询问
    数据
    它是什么,我们可以打印它以查看它确实是您的文件内容,而无需任何转义:

    > data.class
     => String
    > puts data
    [{name: "Muhammad"},{name: "Mahmoud"}]
     => nil
    
    现在让我们试试
    File.readlines

    > lines = File.readlines('file.txt')
     => ["[{name: \"Muhammad\"},{name: \"Mahmoud\"}]\n"]
    
    请注意,括号中的字符串与我们之前使用的字符串相同。这是一个数组,其中包含一个字符串,该字符串是文件中的第一(唯一)行

    > lines.class
     => Array
    > lines.size
     => 1
    > puts lines.first
    [{name: "Muhammad"},{name: "Mahmoud"}]
     => nil
    > lines.first == data
     => true
    
    现在我们可以看到您看到的错误。当您使用
    readlines
    然后添加
    hash
    时,您是在向数组添加hash。这在Ruby中是完全合法的,因为可以使用包含不同类型元素的数组。当您添加
    散列
    时,最终得到一个包含字符串和散列的数组

    > hash = {name: "Ahmed"}
     => {:name=>"Ahmed"}
    > lines << hash
     => ["[{name: \"Muhammad\"},{name: \"Mahmoud\"}]\n", {:name=>"Ahmed"}]
    > lines.map(&:class)
     => [String, Hash]
    > lines.size
     => 2
    
    因此,为了回答标题问题,您可以向数组中添加一个哈希,您只是没有意识到您已经添加了,并且您的数组最初没有包含您希望它包含的数据

    要将文件作为包含哈希的Ruby数组读入,可以使用
    eval
    ,它执行包含Ruby代码的字符串。这通常是不可取的,因为例如,如果您在其他人提供的数据上运行它,它可能包含您并不真正想要执行的代码。由于您控制此文件,并且它是您自己的数据,因此在这种情况下它足够安全

    > real_data = eval(File.read('file.txt'))
     => [{:name=>"Muhammad"}, {:name=>"Mahmoud"}]
    > real_data.class
     => Array
    > real_data.first
     => {:name=>"Muhammad"}
    > real_data << hash
     => [{:name=>"Muhammad"}, {:name=>"Mahmoud"}, {:name=>"Ahmed"}]
    
    real_data=eval(File.read('File.txt')) =>[{:name=>“穆罕默德”},{:name=>“马哈茂德”}] >real_data.class =>阵列 >实数第一 =>{:name=>“穆罕默德”} >真实数据[{:name=>“穆罕默德”},{:name=>“马哈茂德”},{:name=>“艾哈迈德”}]
    现在,您有了一个包含Ruby哈希的Ruby数组,您可以按预期的方式添加另一个哈希。

    [{:name“Muhammad”},{:name“Mahmoud”}]
    抛出错误(它不是有效的哈希或数组),我想知道这段代码是如何工作的……文件只包含字符,没有数组或其他Ruby对象。假设这些字符是
    '[{:name“Muhammad”},{:name“Mahmoud”}]
    。您可以将其读入字符串:
    str=File.read(File.txt)#=>“[{:name\'Muhammad\},{:name\'Mahmoud\'}]””
    。(请不要使用全局变量!)。如果
    hash#=>{:a=>1}
    ,比如说,
    str Serhat,你需要
    [{:name=>“穆罕默德”},{:name=>“马哈茂德”}]
    或者
    [{name:“马哈茂德”},{name:“马哈茂德”}
    @CarySwoveland:我完全知道遗漏了什么或键入错误,我只是想知道——举个例子——这是如何工作的……karatedog,那么你看不到我所有的代码,你怎么能做出这样的评论,代码运行得很好,但是重写了文件,我也很好奇,Cary,我在这里使用了全局变量,因为我从一个lot函数中获取这个值,向这个函数添加局部变量不是很健康(在我看来),我不知道通过你的这个答案我学到了这么多东西,非常感谢,我的代码是通过use eval工作的。