我正在尝试将数组转换为哈希。数组项 = 索引。字符串的值 = 字符串.长度 整数的值 = 整数^2


myarray = ["Hello", 5, "Hi"]
def arrayToHash(array)
  newHash = Hash.new()
  array.each do |x|
    if x.is_a? String
      newHash[x.to_sym] = x.length
    elsif x.is_a? Integer
      newHash[x] = x*x
    else
      newHash[x] = nil
    end
  end
end
arrayToHash(myarray)
puts newHash

我越来越"undefined local variable or method 'newHash' for #<Context:0x7a58c8>"

我是新手,所以任何帮助将不胜感激。

你的代码很好,但它只是在方法内部创建newHash。 它是一个局部变量,当方法返回时会消失。 所以你希望该方法return值:

def arrayToHash(array)
  newHash = Hash.new()
  array.each do |x|
    if x.is_a? String
      newHash[x.to_sym] = x.length
    elsif x.is_a? Integer
      newHash[x] = x*x
    else
      newHash[x] = nil
    end
  end
  return newHash
end

然后,当您调用该方法时,您必须将返回值分配给某些内容:

myHash = arrayToHash(myarray)

一些改进,或者至少更改以使其更惯用的 Ruby。

  1. 这纯粹是装饰性的,但 Rubyists 更喜欢names_like_this而不是namesLikeThis . 所以array_to_hashmy_array等。
  2. 如果您只需要一个普通的空哈希,您可以使用 {} 而不是 Hash.new()
  3. 通常,任何时候您发现自己创建了一个新对象,然后循环访问某些内容以向该对象添加内容,您可以通过对 mapreduce 的单个调用来完成相同的工作。 在这种情况下:

    my_hash = my_array.reduce({}) do |new_hash, x|
      if x.is_a? String
       new_hash[x.to_sym] = x.length
      elsif x.is_a? Integer
        new_hash[x] = x*x
      else
        new_hash[x] = nil
      end
      new_hash
    end
    

看起来你很接近。这就是我会这样做的:

def array_to_hash(array)
  array.reduce({}) do |result, item|
    if item.is_a? String
      result.merge(item.to_sym => item.length)
    elsif item.is_a? Integer
      result.merge(item => item * item)
    end
  end
end
array_to_hash(["Hello", 5, "Hi"])
=> {:Hello=>5, 5=>25, :Hi=>2}

尝试下面的代码,

def array_to_hash(array)
 rb_hash = Hash.new do |hash, key|
                   if key.is_a? String
                      hash[key.to_sym] = key.length
                   elsif key.is_a? Integer
                      hash[key] = key ** 2
                   else
                      nil
                   end
           end
 array.each do |elem| rb_hash[elem] end
 rb_hash
end  

>newHasharrayToHash方法的局部变量,它仅有效且可从内部访问。您可能希望从方法内部调用它,也许就在您退出它之前。

myarray = ["Hello", 5, "Hi"]
def arrayToHash(array)
  newHash = Hash.new()
  array.each do |x|
    if x.is_a? String
      newHash[x.to_sym] = x.length
    elsif x.is_a? Integer
      newHash[x] = x*x
    else
      newHash[x] = nil
    end
  end
  puts newHash # =>{:Hello=>5, 5=>25, :Hi=>2}
end
arrayToHash(myarray)

还有一个变体:

def array_to_hash(array)
  array.each_with_object({}) do |x, hash|
    case x
    when String
      hash[x.to_sym] = x.length
    when Integer
      hash[x] = x*x
    else
      hash[x] = nil
    end
  end
end
array_to_hash( ["Hello", 5, "Hi"] )
  #=> { :Hello => 5, 5 => 25, :Hi => 2 }

我已经更改了一些变量名称以符合 Ruby 的命名约定。 你不必这样做,但大多数 Rubyist 都遵循惯例。

最新更新