Удалить / сквош записи в вертикальном хеше - PullRequest
0 голосов
/ 24 марта 2010

У меня есть сетка, которая представляет собой матрицу 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] => у Рафаэля нет элемента перед, если (скажем, нет [16,3] существует), тогда [17,3] должно стать [16,3] и т. Д.

Таким образом, в основном все пустые элементы будут выталкиваться из вертикальной структуры (строки) хеша.

Есть ли функции, на которые мне следует взглянуть, или есть простой метод, похожий на сквош, который просто удаляет пробелы, корректирует и перемещает другие элементы?

Заранее спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 24 марта 2010

Вот мой выстрел (вероятно, не самый быстрый):

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 работал правильно.

Так и должно быть. :)

0 голосов
/ 24 марта 2010

Хорошо ... Я думаю, я понимаю, что вы хотите, чтобы он делал; Вот как бы я это сделал:

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

...