Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
合并Ruby数组_Ruby_Arrays_Merge - Fatal编程技术网

合并Ruby数组

合并Ruby数组,ruby,arrays,merge,Ruby,Arrays,Merge,我有几个类为UserInfo的Ruby对象数组: class UserInfo attr_accessor :name, :title, :age end 如何将这些数组合并到一个数组中?用户由其名称标识,因此我不希望有重复的名称。如果姓名、头衔、年龄等相等,我希望在新数组中有1个条目。如果名称相同,但任何其他细节不同,我可能希望位于不同阵列中的这两个用户手动修复错误 提前感谢一年前对象上的一种神秘的实例变量\u比较。我想你可以用这个 class Object def inst

我有几个类为
UserInfo
的Ruby对象数组:

class UserInfo  
    attr_accessor :name, :title, :age
end
如何将这些数组合并到一个数组中?用户由其名称标识,因此我不希望有重复的名称。如果姓名、头衔、年龄等相等,我希望在新数组中有1个条目。如果名称相同,但任何其他细节不同,我可能希望位于不同阵列中的这两个用户手动修复错误

提前感谢

一年前
对象上的一种神秘的
实例变量\u比较
。我想你可以用这个

class Object
  def instance_variables_compare(o)
    Hash[*self.instance_variables.map {|v|
      self.instance_variable_get(v)!=o.instance_variable_get(v) ? 
      [v,o.instance_variable_get(v)] : []}.flatten]
  end
end
一个俗气的例子

require 'Date'

class Cheese
  attr_accessor :name, :weight, :expire_date
  def initialize(name, weight, expire_date)
    @name, @weight, @expire_date = name, weight, expire_date
  end
end

stilton=Cheese.new('Stilton', 250, Date.parse("2010-12-02"))
gorgonzola=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola", "@expire_date"=>#<Date: 4910305/2,0,2299161>}
>> gorgonzola.instance_variables_compare(stilton)
=> {"@name"=>"Stilton", "@expire_date"=>#<Date: 4910275/2,0,2299161>}
>> stilton.expire_date=gorgonzola.expire_date
=> #<Date: 4910305/2,0,2299161>
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola"}
>> stilton.instance_variables_compare(stilton)
=> {}
stilton2=Cheese.new('Stilton', 210, Date.parse("2010-12-02"))
gorgonzola2=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))

arr=[]<<stilton<<stilton2<<gorgonzola<<gorgonzola2
irb是我选择的武器

require 'Date'

class Cheese
  attr_accessor :name, :weight, :expire_date
  def initialize(name, weight, expire_date)
    @name, @weight, @expire_date = name, weight, expire_date
  end
end

stilton=Cheese.new('Stilton', 250, Date.parse("2010-12-02"))
gorgonzola=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola", "@expire_date"=>#<Date: 4910305/2,0,2299161>}
>> gorgonzola.instance_variables_compare(stilton)
=> {"@name"=>"Stilton", "@expire_date"=>#<Date: 4910275/2,0,2299161>}
>> stilton.expire_date=gorgonzola.expire_date
=> #<Date: 4910305/2,0,2299161>
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola"}
>> stilton.instance_variables_compare(stilton)
=> {}
stilton2=Cheese.new('Stilton', 210, Date.parse("2010-12-02"))
gorgonzola2=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))

arr=[]<<stilton<<stilton2<<gorgonzola<<gorgonzola2
一个哈希值没有问题,一个哈希值有问题

h={}
problems=Hash.new([])

arr.each {|c| 
  if h.has_key?(c.name)
    if problems.has_key?(c.name)
      problems[c.name]=problems[c.name]<<c
    elsif h[c.name].instance_variables_compare(c) != {}
      problems[c.name]=problems[c.name]<<c<<h[c.name]
      h.delete(c.name)
    end
  else 
    h[c.name]=c
  end
}
据我所知,您根本不需要修改此代码来支持
UserInfo
对象数组

直接比较属性或覆盖
=
可能会快得多。这就是覆盖
==

def ==(other)
  return self.weight == other.weight && self.expire_date == other.expire_date
end
循环变成这个

arr.each {|c| 
  if h.has_key?(c.name)
    if problems.has_key?(c.name)
      problems[c.name]=problems[c.name]<<c
    elsif h[c.name] != c
      problems[c.name]=problems[c.name]<<c<<h[c.name]
      h.delete(c.name)
    end
  else 
    h[c.name]=c
  end
}
一年前,在
对象上有一种神秘的
实例变量\u compare
。我想你可以用这个

class Object
  def instance_variables_compare(o)
    Hash[*self.instance_variables.map {|v|
      self.instance_variable_get(v)!=o.instance_variable_get(v) ? 
      [v,o.instance_variable_get(v)] : []}.flatten]
  end
end
一个俗气的例子

require 'Date'

class Cheese
  attr_accessor :name, :weight, :expire_date
  def initialize(name, weight, expire_date)
    @name, @weight, @expire_date = name, weight, expire_date
  end
end

stilton=Cheese.new('Stilton', 250, Date.parse("2010-12-02"))
gorgonzola=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola", "@expire_date"=>#<Date: 4910305/2,0,2299161>}
>> gorgonzola.instance_variables_compare(stilton)
=> {"@name"=>"Stilton", "@expire_date"=>#<Date: 4910275/2,0,2299161>}
>> stilton.expire_date=gorgonzola.expire_date
=> #<Date: 4910305/2,0,2299161>
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola"}
>> stilton.instance_variables_compare(stilton)
=> {}
stilton2=Cheese.new('Stilton', 210, Date.parse("2010-12-02"))
gorgonzola2=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))

arr=[]<<stilton<<stilton2<<gorgonzola<<gorgonzola2
irb是我选择的武器

require 'Date'

class Cheese
  attr_accessor :name, :weight, :expire_date
  def initialize(name, weight, expire_date)
    @name, @weight, @expire_date = name, weight, expire_date
  end
end

stilton=Cheese.new('Stilton', 250, Date.parse("2010-12-02"))
gorgonzola=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola", "@expire_date"=>#<Date: 4910305/2,0,2299161>}
>> gorgonzola.instance_variables_compare(stilton)
=> {"@name"=>"Stilton", "@expire_date"=>#<Date: 4910275/2,0,2299161>}
>> stilton.expire_date=gorgonzola.expire_date
=> #<Date: 4910305/2,0,2299161>
>> stilton.instance_variables_compare(gorgonzola)
=> {"@name"=>"Gorgonzola"}
>> stilton.instance_variables_compare(stilton)
=> {}
stilton2=Cheese.new('Stilton', 210, Date.parse("2010-12-02"))
gorgonzola2=Cheese.new('Gorgonzola', 250, Date.parse("2010-12-17"))

arr=[]<<stilton<<stilton2<<gorgonzola<<gorgonzola2
一个哈希值没有问题,一个哈希值有问题

h={}
problems=Hash.new([])

arr.each {|c| 
  if h.has_key?(c.name)
    if problems.has_key?(c.name)
      problems[c.name]=problems[c.name]<<c
    elsif h[c.name].instance_variables_compare(c) != {}
      problems[c.name]=problems[c.name]<<c<<h[c.name]
      h.delete(c.name)
    end
  else 
    h[c.name]=c
  end
}
据我所知,您根本不需要修改此代码来支持
UserInfo
对象数组

直接比较属性或覆盖
=
可能会快得多。这就是覆盖
==

def ==(other)
  return self.weight == other.weight && self.expire_date == other.expire_date
end
循环变成这个

arr.each {|c| 
  if h.has_key?(c.name)
    if problems.has_key?(c.name)
      problems[c.name]=problems[c.name]<<c
    elsif h[c.name] != c
      problems[c.name]=problems[c.name]<<c<<h[c.name]
      h.delete(c.name)
    end
  else 
    h[c.name]=c
  end
}

这是另一种可能的方式。如果您有一种识别每个UserInfo的方法,请使用一个to_str方法打印出值:

  def to_str()
    return "#{@name}:#{@title}:#{@age}"
  end
您可以使用inject和hash

all_users = a + b # collection of users to "merge"    
res = all_users.inject({})do |h,v|
  h[v.to_str] = v  #save the value indexed on the string output
  h # return h for the next iteration
end

merged = res.values #the unique users

这是另一种可能的方式。如果您有一种识别每个UserInfo的方法,请使用一个to_str方法打印出值:

  def to_str()
    return "#{@name}:#{@title}:#{@age}"
  end
您可以使用inject和hash

all_users = a + b # collection of users to "merge"    
res = all_users.inject({})do |h,v|
  h[v.to_str] = v  #save the value indexed on the string output
  h # return h for the next iteration
end

merged = res.values #the unique users

在对象上重新定义相等比较,可以使用

然后,您可以按名称排序,并查找仅名称重复项

d = c.sort{ |p,q| p.name <=> q.name } #sort by name
name = ""
e = []
d.each do |item|
  if item.name == name
    e[-1] = [e[-1],item].flatten 
  else
    e << item
  end
end
d=c.sort{| p,q | p.name q.name}#按名称排序
name=“”
e=[]
d、 每个do |项目|
如果item.name==name
e[-1]=[e[-1],项].展平
其他的

e在对象上重新定义相等比较,您可以使用

然后,您可以按名称排序,并查找仅名称重复项

d = c.sort{ |p,q| p.name <=> q.name } #sort by name
name = ""
e = []
d.each do |item|
  if item.name == name
    e[-1] = [e[-1],item].flatten 
  else
    e << item
  end
end
d=c.sort{| p,q | p.name q.name}#按名称排序
name=“”
e=[]
d、 每个do |项目|
如果item.name==name
e[-1]=[e[-1],项].展平
其他的

e当你真正的意思是删除重复项时,你使用动词“合并”。另外,当您询问数组时,您已经用
哈希
标记了它。您可能应该编辑这个问题以使其更清楚。@Olly:将标记从“hash”更改为“arrays”。当您真正的意思是删除重复项时,您可以使用动词merging。另外,当您询问数组时,您已经用
哈希
标记了它。您可能应该编辑此问题以使其更清楚。@Olly:将标记从“hash”更改为“arrays”。它主要是从一篇旧博客文章中复制和粘贴的。另外,我刚刚纠正了一个错误。它主要是从一篇旧博客文章中复制和粘贴的。而且我刚刚纠正了一个错误。