lib/rbbt/util/tsv/attach.rb in rbbt-util-3.1.0 vs lib/rbbt/util/tsv/attach.rb in rbbt-util-3.2.0
- old
+ new
@@ -126,11 +126,11 @@
through do |key, values|
if other.include? key
new_values = other[key].values_at *fields
new_values.collect!{|v| [v]} if type == :double and not other.type == :double
- new_values.collect!{|v| v.nil? ? nil : v.first} if not type == :double and other.type == :double
+ new_values.collect!{|v| v.nil? ? nil : (other.type == :single ? v : v.first)} if not type == :double and other.type == :double
self[key] = self[key].concat new_values
else
if type == :double
self[key] = self[key].concat [[]] * fields.length
else
@@ -149,10 +149,11 @@
field_positions = fields.collect{|field| other.identify_field field}
field_names = field_positions.collect{|pos| pos == :key ? other.key_field : other.fields[pos] }
through do |key, values|
source_keys = values[source]
+ source_keys = [source_keys] unless Array === source_keys
if source_keys.nil? or source_keys.empty?
all_new_values = []
else
all_new_values = []
source_keys.each do |source_key|
@@ -163,12 +164,12 @@
else
other[source_key][pos]
end
end
- new_values.collect!{|v| [v]} if type == :double and not other.type == :double
- new_values.collect!{|v| v.nil? ? nil : v.first} if not type == :double and other.type == :double
+ new_values.collect!{|v| [v]} if type == :double and not other.type == :double
+ new_values.collect!{|v| v.nil? ? nil : (other.type == :single ? v : v.first)} if not type == :double and other.type == :double
all_new_values << new_values
end
end
if all_new_values.empty?
@@ -189,16 +190,16 @@
self.fields = self.fields.concat field_names
end
def attach_index(other, index, fields = nil)
fields = other.fields - [key_field].concat(self.fields) if fields.nil?
+ fields = [fields] unless Array === fields
other = other.tsv unless TSV === other
field_positions = fields.collect{|field| other.identify_field field}
field_names = field_positions.collect{|pos| pos == :key ? other.key_field : other.fields[pos] }
-
length = self.fields.length
through do |key, values|
source_keys = index[key]
if source_keys.nil? or source_keys.empty?
all_new_values = []
@@ -216,20 +217,20 @@
else
other[source_key][pos]
end
end
new_values.collect!{|v| v.nil? ? [[]] : [v]} if type == :double and not other.type == :double
- new_values.collect!{|v| v.nil? ? nil : v.first} if not type == :double and other.type == :double
+ new_values.collect!{|v| v.nil? ? nil : (other.type == :single ? v : v.first)} if not type == :double and other.type == :double
all_new_values << new_values
end
end
if all_new_values.empty?
if type == :double
all_new_values = [[[]] * field_positions.length]
else
- all_new_values = [[""] * field_positions.length]
+ all_new_values = [[""] * field_positions.length]
end
end
current = self[key]
@@ -258,11 +259,15 @@
def self.find_path(files, options = {})
options = Misc.add_defaults options, :in_namespace => false
in_namespace = options[:in_namespace]
if in_namespace
- ids = [files.first.all_namespace_fields(in_namespace)]
+ if files.first.all_fields.include? in_namespace
+ ids = [[in_namespace]]
+ else
+ ids = [files.first.all_namespace_fields(in_namespace)]
+ end
ids += files[1..-1].collect{|f| f.all_fields}
else
ids = files.collect{|f| f.all_fields}
end
id_list = []
@@ -274,11 +279,11 @@
}
return nil if match.empty?
id_list << match.first
end
- if id_list.last.first != files.last.all_fields.first
+ if id_list.last != files.last.all_fields.first
id_list << files.last.all_fields.first
id_list.zip(files)
else
id_list.zip(files[0..-1])
end
@@ -310,18 +315,18 @@
current_key = data_key
while not path.empty?
next_key, next_file = path.shift
if current_index.nil?
- current_index = next_file.index :target => next_key, :fields => current_key, :persistence => persist_input
+ current_index = next_file.index :target => next_key, :fields => current_key, :persistence => (persist_input and path.empty?)
else
next_index = next_file.index :target => next_key, :fields => current_key, :persistence => persist_input
current_index.process current_index.fields.first do |values|
if values.nil?
nil
else
- next_index.values_at(*values).flatten.collect
+ next_index.values_at(*values).flatten.collect.to_a
end
end
current_index.fields = [next_key]
end
current_key = next_key
@@ -394,29 +399,15 @@
self.fields.each_with_index{|field,i| detached_fields << i if file_fields.include? field.fullname}
reorder :key, detached_fields
end
def paste(other, options = {})
- tmpfile = TmpFile.tmp_file
- TSV.paste(self.to_s, other.to_s, tmpfile)
-
- new = TSV.new(tmpfile, options)
-
- new.key_field = self.key_field unless self.key_field.nil?
- if self.fields and other.fields
- new.fields = self.fields + other.fields
- end
-
- FileUtils.rm tmpfile if File.exists? tmpfile
-
- new
- end
-
-
- def paste(other, options = {})
TmpFile.with_file do |output|
TSV.paste_merge(self, other, output, options[:sep] || "\t")
- TSV.new output, options
+ tsv = TSV.new output, options
+ tsv.key_field = self.key_field unless self.key_field.nil?
+ tsv.fields = self.fields + other.fields unless self.fields.nil? or other.fields.nil?
+ tsv
end
end
def self.fast_paste(files, delim = "$")
CMD.cmd("paste #{ files.collect{|f| "'#{f}'"} * " "} -d'#{delim}' |sed 's/#{delim}[^\\t]*//g'", :pipe => true)