Как дедуплицировать массив с вариациями подстрок, где одна подстрока имеет приоритет над другой? - PullRequest
0 голосов
/ 11 октября 2011

У меня есть набор данных, похожий на этот: http://pastie.org/private/3u1reg72nnjfsgqzgqzwra

Список - это набор имен файлов, которые необходимо обработать. Если имя файла с подстрокой 10u существует вместе с именем с подстрокой 2u, имя файла с 10u содержит подмножество данных из файла с подстрокой 2u. Другими словами, когда у вас есть что-то вроде:

20021203_V9ut_2u.txt 
20021203_V9ut_10u.txt 
    or 
V9cd_2u.txt
V9cd_10u.txt

20021203_V9ut_10u.txt и V9cd_10u.txt должны быть удалены из списка, и только имена файлов с 1u должны оставаться в списке.

Я пробовал несколько разных методов, но все они слишком похожи на С или хакерские. Я также думал о разделении строки и создании хэша со значениями 1u или 10u, а затем, если существует ключ со значением 10u, замените его на 1u, иначе отбросьте затем переназначить хэш в массив для обработки содержимого файла.

Каков «лучший» или самый рубиновый способ сделать это, и можете ли вы привести пример?

Ответы [ 3 ]

2 голосов
/ 11 октября 2011

Если ваш список файлов иногда содержит файлы, которые не имеют идеального соответствия 2u и 10u, это поможет вам. Он удаляет файлы 10u, если и только если существует соответствующий файл 2u, в противном случае оставляет его в результирующем списке.

files = %w(20021203_V9ut_2u.txt 
20021203_V9ut_10u.txt 
V9cd_2u.txt
V9cd_10u.txt
test1_2u.txt
thing2_10u.txt)

# Reverse sort them if they aren't already that way

files = files.sort {|a,b| b <=> a }

puts files.inspect

scrubbed_files = []
files.each_with_index { |f,i| 
  scrubbed_files << f unless f =~ /(.*)_10u\.(.*)/ && files[i-1] =~ /#{$1}_2u\.#{$2}/
}

puts scrubbed_files.inspect
2 голосов
/ 11 октября 2011

Предполагая, что у вас есть массив all_filenames в виде строк:

filenames_2u = all_filenames.reject!{ |f| f =~ /10u/ } # edited to be actual working ruby

edit Если файл, который вы указали, является тем, с чем вы работаете:

all_filenames = IO.readlines('filenames.txt')
1 голос
/ 11 октября 2011

Так веселее:

a.map {|x| x.split(/_/)}.group_by {|x| x[0...-1]}.map {|_,xx| xx.sort_by {|x| x.last.to_i}.first.join("_")}

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

Это будет работать для любой схемы нумерации Xu, поэтому, если у вас есть 2u, 5u и 10u, вы получите версию 2u, а если у вас есть 10u и 20u, вы получите 10u.

group_by это круто.

...