【问题标题】:Ruby, loop over array of variable names, apply method to each and replace variable valueRuby,遍历变量名数组,将方法应用于每个变量并替换变量值
【发布时间】:2015-12-16 17:20:16
【问题描述】:

我有一个变量数组,每个变量都是一个类名字符串数组。我想循环遍历每个变量,并将这些变量的值替换为应用函数的返回值。

我尝试使用 #map! 进行对象修改,但这似乎不起作用。

choose_one_classes = ["ramjet-transform"]
add_classes = ["btn", "btn-md", "btn-success"]
list_group_classes = ["list-group", "list-group-border", "choose-one-list"]

[choose_one_classes, add_classes, list_group_classes].map! do |var|
  var.join(" ")
end

我知道我可以这样做:

choose_one_classes, add_classes, list_group_classes = [choose_one_classes, add_classes, list_group_classes].map do |var|
  var.join(" ")
end

但我希望有另一种更好的方法。我想从技术上讲,我想做的事情并不“伟大”,因为我应该坚持不修改变量,因为良好的功能实践、线程等。但我很好奇。

编辑

预期结果:

choose_one_classes = "ramjet-transform"
add_classes = "btn btn-md btn-success"
list_group_classes = "list-group list-group-border choose-one-list"

【问题讨论】:

  • 您可以编辑您的问题以包含您的预期结果吗?
  • 问题是在 Ruby 中没有按名称分配实例变量的好方法。这几乎是设计使然。你甚至不能再用eval 做到这一点。正如您所指出的,您尝试做的事情并不“好”。如果您能更详细地解释您试图通过这样做解决的问题,我们可以帮助您找到更好的解决方案?
  • @Jordan,我认为您的意思是“......分配一个局部变量......”。我最初的想法是相同的,但是您的论点与创建局部变量(现在无法完成)有关,而不是以编程方式更改现有局部变量的值,这是另一回事。
  • 是的,你说得对,我的意思是“局部变量”!
  • 如果您发现至少一个答案有用,请考虑选择您认为最有帮助的答案。

标签: arrays ruby


【解决方案1】:

.map!只影响这个隐式创建的数组,等价于如下代码:

all_classes = [choose_one_classes, add_classes, list_group_classes]
all_classes.map! { |e| e.length } # all_classes is modified
all_classes # [1, 3, 3]

但是您需要修改每个数组的成员,而您只能使用 bang 方法(末尾带有感叹号)。这样的 bang-method 不一定非得是.map!,例如:

[choose_one_classes, add_classes, list_group_classes].each do |arr|
  arr.map! { |e| e.upcase }
end
choose_one_classes # ["RAMJET-TRANSFORM"]
add_classes # ["BTN", "BTN-MD", "BTN-SUCCESS"]
list_group_classes # ["LIST-GROUP", "LIST-GROUP-BORDER", "CHOOSE-ONE-LIST"]

但是数组没有方法.join!,因为它们的方法.join返回的是字符串而不是数组。

【讨论】:

  • 您正在修改数组的元素。 OP希望将局部变量的值从数组转换为字符串,这是一个不同的问题。
【解决方案2】:

我的理解是您想以编程方式更改局部变量的值。你可以这样做:

如下:

choose_one_classes = ["ramjet-transform"]
add_classes = ["btn", "btn-md", "btn-success"]
list_group_classes = ["list-group", "list-group-border", "choose-one-list"]

local_vars = local_variables - [:local_vars, :_]
  #=> [:list_group_classes, :add_classes, :choose_one_classes] 
another_local_var = 3

b = binding
  #=> #<Binding:0x007fcd39a10eb0> 

local_vars.each do |var_sym| 
  a = b.local_variable_get(var_sym)
  b.local_variable_set(var_sym, a.join(' '))
end

choose_one_classes
  #=> "ramjet-transform" 
add_classes
  #=> "btn btn-md btn-success" 
list_group_classes
  #=> "list-group list-group-border choose-one-list" 

注意事项:

  • 必须在定义任何其他局部值之前定义感兴趣的局部值,这样local_variables 将只为这些局部变量返回一个符号数组(加上local-vars,它已被删除,但不是another_local_var )。
  • local_variables返回的数组中拉取:_只是为了让代码在IRB中工作。
  • 如果您尝试在 IRB 中运行它,则每次运行时都需要重新加载 IRB。

【讨论】:

    【解决方案3】:

    如果你要经常这样做,你可以做一个这样的方法。

    def join_classes classes
      classes.join(" ")
    end
    

    那你就这样称呼它吧。

    choose_one_classes = join_classes(["ramjet-transform"])
    add_classes = join_classes(["btn", "btn-md", "btn-success"])
    list_group_classes = join_classes(["list-group", "list-group-border", "choose-one-list"])
    

    这会给你这个结果。

    choose_one_classes = "ramjet-transform"
    add_classes = "btn btn-md btn-success"
    list_group_classes = "list-group list-group-border choose-one-list"
    

    但我不得不问,为什么不直接做呢?

    add_classes = ["btn", "btn-md", "btn-success"].join(" ")
    

    add_classes = "btn btn-md btn-success"
    

    似乎这样更容易?您是否从其他地方(例如数据库)提取值?

    【讨论】:

      猜你喜欢
      • 2020-02-14
      • 2020-03-10
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      相关资源
      最近更新 更多