Easy Ruby data table / поисковый вопрос - PullRequest
1 голос
/ 13 августа 2010

Итак, у меня есть таблица, которая выглядит так:

A    B
A    C
B    A
C    A
C    B

Я хочу удалить строки, в которых соединение двух значений уже представлено (поэтому A ---- B является эквивалентным соединением как B ---- A) По сути, я хочу, чтобы мой стол выглядел следующим образом.

A    B
A    C
B    C

Как я могу сделать это в Ruby?

-Bobby

EDIT:

Вот мой текущий код:

require 'rubygems'


f = File.new("uniquename.txt","w")
i = IO.readlines('bioportnetwork.txt').collect{|l| l.split.sort}.uniq
i.each do |z|
f.write(z + "\n")
end

Я попробовал этот код, но я думаю, что IO.readlines неправильно прочитал мои столбцы. Вот одна часть моего стола.

9722,9754   8755
8755         9722,9754
9722,9754   7970,7971
7970,7971    9722,9754  

Как получить правильное чтение, а затем правильно сохранить в виде файла TSV?

-Bobby

Ответы [ 3 ]

3 голосов
/ 13 августа 2010

Итак, допустим, вы загрузили файл TSV в массив пар:

arr = [["A", "B"], ["A", "C"], ["B", "A"], ["C", "A"], ["C", "B"]]
Hash[arr.map{|pair| [pair.sort, pair]}].values
#=> [["B", "A"], ["C", "A"], ["C", "B"]]

Это нормально, если порядок пар в исходном массиве не важен.

Иесли не важен ни один порядок элементов в парах:

arr.map(&:sort).uniq
#=> [["A", "B"], ["A", "C"], ["B", "C"]]
1 голос
/ 13 августа 2010

Эквивалентность множеств определена в ruby, и множества используют эквивалентность только для проверки новых членов, поэтому вы можете использовать структуру вложенного множества, чтобы решить это быстро и легко.

set_of_all_sets = Set.new
file.each_line do |line|
  line =~ /(\S)\s(\S)/
  set_of_all_sets << Set.new([$1, $2])
end
array_of_all_sets.map{|set| set.to_a}
1 голос
/ 13 августа 2010

Я предполагаю, что под таблицей вы подразумеваете массив массивов, подобный следующему:

x = [['A', 'B'],
     ['A', 'C'],
     ['B', 'A'],
     ['C', 'A'],
     ['C', 'B']]

Если это так, вы можете дублировать список с помощью x.collect{|a| a.sort}.uniq.

Обновление: Чтобы прочитать данные из файла в массив, используйте что-то вроде:

lines = IO.readlines('filename.txt')
x = []
lines.each {|l| x << l.split}

Обновление 2: Или вы можете написать одну строчку целиком:

IO.readlines('test.txt').collect{|l| l.split.sort}.uniq

Обновление 3: При записи в файл не используйте IO.write. Он автоматически преобразует массив в строку, которая может быть там, где вы столкнулись с проблемой. Вместо этого используйте IO.puts:

f.puts x[0].to_s << "\t" << x[1].to_s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...