【问题标题】:Ruby: Remove the existing object from an array based on the value when adding a new oneRuby:添加新对象时根据值从数组中删除现有对象
【发布时间】:2021-10-25 05:56:13
【问题描述】:

我是红宝石新手。我有一个名为users的数组

[
 {'name': 'Andy', 'age': 23, 'position': 'manager'},
 {'name': 'Cindy', 'age': 25, 'position': 'HR'},
]

在向数组添加新对象{'name': 'Dave', 'age': 33, 'position': 'manager'} 时,它始终会根据position 键删除现有项目。所以当Dave被添加到数组中时,Andy应该被删除,因为他的位置是“经理”。新数组应该是

[
 {'name': 'Cindy', 'age': 25, 'position': 'HR'},
 {'name': 'Dave', 'age': 33, 'position': 'manager'},
]

我当前的解决方案保留旧项目并删除新项目,这是错误的:(

users.append(user).uniq do |user|
  user.position
end

我正在寻找一种简洁而简短的方法来实现它。谢谢。

【问题讨论】:

  • _将新对象添加到数组 {...} :此 {...} 不是数组。 users 当然是一个数组。
  • 顺便说一句,'name': 'Cindy' 等价于'name'.to_sym => 'Cindy',所以你可以更简单地写成name: 'Cindy'。毕竟,您的键是符号,而不是字符串。
  • @user1934428 谢谢,我已经修改了那句话,让它更清楚

标签: arrays ruby hash


【解决方案1】:

您可以在该索引处找到匹配元素indexdelete_at,然后在该索引处找到insert 新元素。像这样的:

 users = [
 {'name': 'Andy', 'age': 23, 'position': 'manager'},
 {'name': 'Cindy', 'age': 25, 'position': 'HR'},
]

user = {'name': 'Dave', 'age': 33, 'position': 'manager'}

index = users.index{|i| i[:position] == user[:position]}
users.delete_at(index)
users.insert(index, user)

【讨论】:

    【解决方案2】:

    您希望替换数组arr 的元素,因此您需要确定要替换的数组中元素的索引i(使用Array#index,又名find_index),然后只需设置arr[i] 等于替换值。 (参见Array#[]=。)这当然会变异(修改)原始数组。我们可以编写一个简单的方法来做到这一点。

    def sub_hash(arr, replacement_hash, hash_to_replace_name)
      i = arr.index { |h| h[:name] == hash_to_replace_name }
      arr[i] = replacement_hash
      arr
    end
    

    让我们试试吧。

    arr = [{name: 'Andy', age: 23, position: 'manager'},
           {name: 'Cindy', age: 25, position: 'HR'}]
    replacement_hash = {name: 'Dave', age: 33, position: 'manager'}
    hash_to_replace_name = 'Andy'
    
    sub_hash(arr, replacement_hash, hash_to_replace_name)
      #=> [{:name=>"Dave", :age=>33, :position=>"manager"},
      #    {:name=>"Cindy", :age=>25, :position=>"HR"}]
    

    现在:

    arr
      #=> [{:name=>"Dave", :age=>33, :position=>"manager"},
      #    {:name=>"Cindy", :age=>25, :position=>"HR"}]
    

    确认arr 确实发生了变异。

    如果数组不一定包含h[:name] #=> 'Andy' 的哈希h,或者如果原始数组不发生突变,则必须适当修改该方法。为避免arr 发生变异,您可以这样写:

    def sub_hash(arr, replacement_hash, hash_to_replace_name)
      i = arr.index { |h| h[:name] == hash_to_replace_name }
      adup = arr.dup 
      adup[i] = replacement_hash
      adup
    end
    

    请注意,哈希键都是符号。例如,'name': 'Andy':'name'=> 'Andy' 的简写,与name: 'Andy' 相同。定义符号时,仅当符号包含空格 (:'my key') 或以非字母字符 (:'007') 开头时才需要引号。 Ruby 返回以下内容:

    {'name': 'Andy', 'age': 23, 'position': 'manager'}
      #=> {:name=>"Andy", :age=>23, :position=>"manager"}
    {name: 'Andy', age: 23, position: 'manager'}
      #=> {:name=>"Andy", :age=>23, :position=>"manager"}
    

    【讨论】:

      【解决方案3】:

      这是另一种更精简的方法:

      users = [
       {'name': 'Andy', 'age': 23, 'position': 'manager'},
       {'name': 'Cindy', 'age': 25, 'position': 'HR'},
      ]
      
      user = {'name': 'Dave', 'age': 33, 'position': 'manager'}
      
      users.map {|a| a[:position] == user[:position]? user : a}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-04-28
        • 2017-12-01
        • 1970-01-01
        • 2019-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多