删除/压缩垂直哈希中的条目

时间:2010-03-24 15:06:11

标签: ruby hash squash

我有一个表示X,Y矩阵的网格,在这里存储为哈希。

X Y矩阵上的某些点可能有值(作为类型字符串),有些可能没有。

典型的网格可能如下所示:

{[9, 5]=>"Alaina", [10, 3]=>"Courtney", [11, 1]=>"Gladys", [8, 7]=>"Alford", [14, 11]=>"Lesley", [17, 2]=>"Lawson", [0, 5]=>"Katrine", [2, 1]=>"Tyra", [3, 3]=>"Fredy", [1, 7]=>"Magnus", [6, 9]=>"Nels", [7, 11]=>"Kylie", [11, 0]=>"Kellen", [10, 2]=>"Johan", [14, 10]=>"Justice", [0, 4]=>"Barton", [2, 0]=>"Charley", [3, 2]=>"Magnolia", [1, 6]=>"Maximo", [7, 10]=>"Olga", [19, 5]=>"Isadore", [16, 3]=>"Delfina", [17, 1]=>"Noe", [20, 11]=>"Francis", [10, 5]=>"Creola", [9, 3]=>"Bulah", [8, 1]=>"Lempi", [11, 7]=>"Raquel", [13, 11]=>"Jace", [1, 5]=>"Garth", [3, 1]=>"Ernest", [2, 3]=>"Malcolm", [0, 7]=>"Alejandrin", [7, 9]=>"Marina", [6, 11]=>"Otilia", [16, 2]=>"Hailey", [20, 10]=>"Brandt", [8, 0]=>"Madeline", [9, 2]=>"Leanne", [13, 10]=>"Jenifer", [1, 4]=>"Humberto", [3, 0]=>"Nicholaus", [2, 2]=>"Nadia", [0, 6]=>"Abigail", [6, 10]=>"Zola", [20, 5]=>"Clementina", [23, 3]=>"Alvah", [19, 11]=>"Wallace", [11, 5]=>"Tracey", [8, 3]=>"Hulda", [9, 1]=>"Jedidiah", [10, 7]=>"Annetta", [12, 11]=>"Nicole", [2, 5]=>"Alison", [0, 1]=>"Wilma", [1, 3]=>"Shana", [3, 7]=>"Judd", [4, 9]=>"Lucio", [5, 11]=>"Hardy", [19, 10]=>"Immanuel", [9, 0]=>"Uriel", [8, 2]=>"Milton", [12, 10]=>"Elody", [5, 10]=>"Alexanne", [1, 2]=>"Lauretta", [0, 0]=>"Louvenia", [2, 4]=>"Adelia", [21, 5]=>"Erling", [18, 11]=>"Corene", [22, 3]=>"Haskell", [11, 11]=>"Leta", [10, 9]=>"Terrence", [14, 1]=>"Giuseppe", [15, 3]=>"Silas", [12, 5]=>"Johnnie", [4, 11]=>"Aurelie", [5, 9]=>"Meggie", [2, 7]=>"Phoebe", [0, 3]=>"Sister", [1, 1]=>"Violet", [3, 5]=>"Lilian", [18, 10]=>"Eusebio", [11, 10]=>"Emma", [15, 2]=>"Theodore", [14, 0]=>"Cassidy", [4, 10]=>"Edmund", [2, 6]=>"Claire", [0, 2]=>"Madisen", [1, 0]=>"Kasey", [3, 4]=>"Elijah", [17, 11]=>"Susana", [20, 1]=>"Nicklaus", [21, 3]=>"Kelsie", [10, 11]=>"Garnett", [11, 9]=>"Emanuel", [15, 1]=>"Louvenia", [14, 3]=>"Otho", [13, 5]=>"Vincenza", [3, 11]=>"Tate", [2, 9]=>"Beau", [5, 7]=>"Jason", [6, 1]=>"Jayde", [7, 3]=>"Lamont", [4, 5]=>"Curt", [17, 10]=>"Mack", [21, 2]=>"Lilyan", [10, 10]=>"Ruthe", [14, 2]=>"Georgianna", [4, 4]=>"Nyasia", [6, 0]=>"Sadie", [16, 11]=>"Emil", [21, 1]=>"Melba", [20, 3]=>"Delia", [3, 10]=>"Rosalee", [2, 8]=>"Myrtle", [7, 2]=>"Rigoberto", [14, 5]=>"Jedidiah", [13, 3]=>"Flavie", [12, 1]=>"Evie", [8, 9]=>"Olaf", [9, 11]=>"Stan", [20, 2]=>"Judge", [5, 5]=>"Cassie", [7, 1]=>"Gracie", [6, 3]=>"Armando", [4, 7]=>"Delia", [3, 9]=>"Marley", [16, 10]=>"Robyn", [2, 11]=>"Richie", [12, 0]=>"Gilberto", [13, 2]=>"Dedrick", [9, 10]=>"Liam", [5, 4]=>"Jabari", [7, 0]=>"Enola", [6, 2]=>"Lela", [3, 8]=>"Jade", [2, 10]=>"Johnson", [15, 5]=>"Willow", [12, 3]=>"Fredrick", [13, 1]=>"Beau", [9, 9]=>"Carlie", [8, 11]=>"Daisha", [6, 5]=>"Declan", [4, 1]=>"Carolina", [5, 3]=>"Cruz", [7, 7]=>"Jaime", [0, 9]=>"Anthony", [1, 11]=>"Esta", [13, 0]=>"Shaina", [12, 2]=>"Alec", [8, 10]=>"Lora", [6, 4]=>"Emely", [4, 0]=>"Rodger", [5, 2]=>"Cedrick", [0, 8]=>"Collin", [1, 10]=>"Armani", [16, 5]=>"Brooks", [19, 3]=>"Eleanora", [18, 1]=>"Alva", [7, 5]=>"Melissa", [5, 1]=>"Tabitha", [4, 3]=>"Aniya", [6, 7]=>"Marc", [1, 9]=>"Marjorie", [0, 11]=>"Arvilla", [19, 2]=>"Adela", [7, 4]=>"Zakary", [5, 0]=>"Emely", [4, 2]=>"Alison", [1, 8]=>"Lorenz", [0, 10]=>"Lisandro", [17, 5]=>"Aylin", [18, 3]=>"Giles", [19, 1]=>"Kyleigh", [8, 5]=>"Mary", [11, 3]=>"Claire", [10, 1]=>"Avis", [9, 7]=>"Manuela", [15, 11]=>"Chesley", [18, 2]=>"Kristopher", [24, 3]=>"Zola", [8, 4]=>"Pietro", [10, 0]=>"Delores", [11, 2]=>"Timmy", [15, 10]=>"Khalil", [18, 5]=>"Trudie", [17, 3]=>"Rafael", [16, 1]=>"Anthony"}

我需要做的是基本上删除所有空条目。

假设[17,3] =>拉斐尔在if前面没有元素(比方说 - 没有[16,3]存在)然后[17,3]应该变成[16,3]等。

所以基本上所有空项都将从哈希的垂直(行)结构中弹出。

是否有我应该看一下的功能,或者是否有简单的类似壁球的方法,只需删除空白并调整和移动其他项目?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这是我的镜头(可能不是最快的):

data.group_by{|k,v| k[1]}.inject({}){|a,(k,v)|
  v.sort_by{|i| i[0][0]}.each_with_index{|elem,i|
    a[[i,elem[0][1]]] = elem[1]
  }
  a
}

这里的输入子集适合测试:

{[9, 5]=>"Alaina", [10, 3]=>"Courtney", [11, 5]=>"Gladys", [8, 5]=>"Alford"}

应该导致:

{[0, 5]=>"Alford", [1, 5]=>"Alaina", [2, 5]=>"Gladys", [0, 3]=>"Courtney"}

逐步说明(您可以在irb中进行试验):

我们需要group-by因为我们应该分别处理每一行,所以首先我们按行分组记录,制作数组的哈希值(让我们调用这些数组r

data.group_by{|k,v| k[1]}
# => {5=>[[[9, 5], "Alaina"], [[11, 5], "Gladys"], [[8, 5], "Alford"]], 3=>[[[10, 3], "Courtney"]]}

inject因此我们可以创建输出哈希,我们从空的哈希开始,我们将一次添加“转换”元素。转换只是用“压缩”索引替换列索引,因此想法是以某种方式将数组[8, 9, 11]映射到[0, 1, 2](处理第5行时)。这就是为什么我们需要对数组r进行排序(让我们调用已排序的数组rs):

r = [[[9, 5], "Alaina"], [[11, 5], "Gladys"], [[8, 5], "Alford"]]
rs = r.sort_by{|i| i[0][0]}
#=> [[[8, 5], "Alford"], [[9, 5], "Alaina"], [[11, 5], "Gladys"]]

然后在rs中为每个元素分配一个索引,从0开始。我们使用each_with_index,以便在elem, i中我们得到诸如

之类的对
[[8, 5], "Alford"], 0
[[9, 5], "Alaina"], 1
[[11, 5], "Gladys"], 2

现在我们需要所有数字来填充生成的哈希a

a[[i,elem[0][1]]] = elem[1]

所以

a[[0,5]] = 'Alford'
a[[1,5]] = 'Alaina'
etc.

我们需要从a的块中返回inject(累加器)才能正常工作。

那应该是它。 :)

答案 1 :(得分:0)

好的......我想我得到了你想做的事;我将如何做到这一点:

data = # the hash in the format above
rows = [] # a new array

# then place each row in the entry of rows corresponding to it's y value at
# the index of it's x value
data.each_pair {|key, value| rows[key[1]] ||= []; rows[key[1]][key[0]] = value }

# compact the x values (if there is an adjacent lower x available move to it)
# this is what i believe you meant in your example
rows.map(&:compact!)

# clear out the old data
data = {}

# fill the hash back up using the new compacted data
rows.each_with_index { |xs, y| xs.each_with_index { |entry, x| data[[x,y]] = entry } }

在您的数据上测试它(以及添加一些更难的x值),它似乎有效:)

Roja的