【问题标题】:Get variable whose value is the maximum in an array获取数组中值为最大值的变量
【发布时间】:2016-03-28 06:12:30
【问题描述】:

如果我在 Ruby 中有一个变量数组:

a = 4
b = 7
c = 1

array = [a, b, c]

如何访问具有最高值的变量的名称? (在此示例中为 b)我想检索对具有最高值的元素的引用,以便以后能够对其进行操作:

b += 10 

我试过array.max,但这只是返回最大值7

【问题讨论】:

  • 不清楚你的意思。不是b7吗?
  • 确实需要仔细阅读才能理解,但我认为需要引用b,而不仅仅是b 的值。
  • @DanielStevens 是的,这就是我应该说的。

标签: arrays ruby


【解决方案1】:

当您通过编写array = [a, b, c] 构建数组时,数组中的点不会与名为abc 的变量保持任何关联,因此您无法做你所说的。这些变量可以改变而不影响数组。

您可以更改存储数据的方式以实现这一点,但在不知道您存储什么数据的情况下,很难推荐一个好的方法来做这件事。您可以考虑将数据存储在散列而不是松散变量和数组中:

hash = { a: 4, b: 7, c: 1}

【讨论】:

  • 您可以继续确定密钥:hash.key(hash.values.max)
【解决方案2】:

Ruby 不支持通过引用传递对象,这实际上是您想要做的。当您调用array.max 时,您将获得Fixnum 7 的副本,并且分配和修改将应用于此副本。

也就是说,不能存储对这个Array元素的引用,以后再修改。但是,您可以使用以下方法在现场修改最大值:

array[array.index(array.max)] = array.max + 10
#=> 17

array
#=> [4, 17, 1]

注意当Array中有重复值时,array.index(array.max)会返回第一个的索引。

存储索引以供以后使用并不是一个可靠的解决方案,因为虽然 Ruby 中的 Arrays 是有序的,但 Array 或其元素可以在您检索索引的点和您存储的点之间修改决定改变对应的值。


Another answer 建议有一个 hack 来模仿 pass-by-reference 行为,但这样做会违背语言的意图,并且可能会导致很多痛苦。

【讨论】:

  • 像哈希和数组这样的对象总是通过引用传递。我想你的意思是说别的,比如变量不能通过引用传递。
【解决方案3】:

您可以为此使用Array#index..

1.9.3-p484 :008 > max_elem = array.index(array.max)
 => 1
1.9.3-p484 :009 > array[max_elem] = array[max_elem] + 10
 => 11
1.9.3-p484 :010 > array
 => [4, 17, 1]
1.9.3-p484 :011 >

【讨论】:

    【解决方案4】:

    如果您尝试操纵三个值中的最大值,那么最好执行以下操作:

    array.max + 10  # or any other manipulation for that matter.
    

    如果您问的是学术目的,那么您可以使用 Ruby 的 Binding 来检查局部变量的值。

    a = 4
    b = 7
    c = 1
    
    array = [a, b, c]
    
    # Select variable whose value matches with maximum of three elements
    # Variable's name as symbol is obtained by this process
    var = binding.send(:local_variables).select do |i| 
        array.max.eql? binding.local_variable_get(i)
    end.first
    #=> :b
    
    # Update value of variable using symbol representing  its name
    binding.local_variable_set(var, binding.local_variable_get(var) + 10)
    
    puts b
    #=> 17
    

    您也可以使用Binding#eval 来操作变量,例如:

    binding.eval("#{var.to_s} += 10")
    #=> 17
    

    注意,我们需要使用var.to_s,因为var包含一个符号,我们需要将其转换为字符串,得到可以在eval中使用的变量名字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 2011-08-16
      相关资源
      最近更新 更多