swak 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/swak/table.rb +68 -22
  2. metadata +2 -2
@@ -1,43 +1,84 @@
1
1
  module Swak
2
2
  module Table
3
- def Table.read(io_or_fn, opts={:has_header => false, :type => String, :delim => "\t"})
3
+ class SmartRow
4
+ attr_reader :header, :fields, :colmap
5
+
6
+ def initialize(header, fields)
7
+ if header.size != fields.size
8
+ raise "Header and field size mismatch in SmartRow.new #{header.inspect} vs #{fields.inspect}"
9
+ end
10
+
11
+ @header = header
12
+ @fields = fields
13
+ @colmap = {}
14
+ header.each_with_index {|fieldname, i| @colmap[fieldname] = i}
15
+ if @colmap.size != @header.size
16
+ raise "Duplicate field names not allowed in SmartRow header"
17
+ end
18
+ end
19
+
20
+ def [](*args)
21
+ if args.size == 1 && args[0].is_a?(String)
22
+ @fields[@colmap[args[0]]]
23
+ else
24
+ @fields[*args]
25
+ end
26
+ end
27
+
28
+ def []=(*args)
29
+ if args.size == 2 && args[0].is_a?(String)
30
+ @fields[@colmap[args[0]]] = args[-1]
31
+ else
32
+ @fields.[]=(*args)
33
+ end
34
+ end
35
+
36
+ def method_missing(sym, *args, &block)
37
+ @fields.send(sym, *args, &block)
38
+ end
39
+ end
40
+
41
+
42
+ def Table.read(io_or_fn, opts={:has_header => false, :type => String, :delim => "\t", :smart => false})
4
43
  if io_or_fn.is_a?(String)
5
44
  io = File.new(io_or_fn)
6
45
  else
7
46
  io = io_or_fn
8
47
  end
9
- if opts[:has_header]
10
- header = io.gets
11
- opts[:header] = header.chomp
48
+ if opts[:has_header] || opts[:smart]
49
+ header = io.gets.chomp
50
+ opts[:header] = header
12
51
  end
13
52
 
14
53
  table = []
15
54
  delim = opts[:delim] || "\t"
16
55
 
17
- if (opts[:type] == Integer)
18
- for line in io
19
- line.chomp!
20
- f = line.split(delim)
21
- table << f.map{|x| x.to_i_strict}
22
- end
23
- elsif (opts[:type] == Float)
24
- for line in io
25
- line.chomp!
26
- f = line.chomp.split(delim)
27
- table << f.map{|x| x.to_f_strict}
28
- end
29
- else # Assume String
30
- for line in io
31
- line.chomp!
32
- table << line.split(delim)
33
- end
56
+ case opts[:type].to_s
57
+ when "Integer"
58
+ ele_proc = Proc.new{|ele| ele.to_i_strict}
59
+ when "Float"
60
+ ele_proc = Proc.new{|ele| ele.to_f_strict}
61
+ else
62
+ ele_proc = Proc.new{|ele| ele} # By default, don't format
63
+ end
64
+
65
+ if opts[:smart]
66
+ row_proc = Proc.new{|row| SmartRow.new(header.split(delim), row) }
67
+ else
68
+ row_proc = Proc.new{|row| row}
69
+ end
70
+
71
+ for line in io
72
+ line.chomp!
73
+ f = line.split(delim)
74
+ table << row_proc.call(f.map(&ele_proc))
34
75
  end
35
76
 
36
77
  return table
37
78
  end
38
79
 
39
80
  def Table.write(table, io_or_fn, opts={:header => nil, :fmt => nil, :delim => "\t"})
40
- raise "Illegal fmt in Swak::Table.write" if !opts[:fmt].nil? && !opts[:fmt].is_a?(String)
81
+ raise "Illegal fmt in Swak::Table.write: #{opts.inspect}" if !opts[:fmt].nil? && !opts[:fmt].is_a?(String)
41
82
 
42
83
  delim = opts[:delim] || "\t"
43
84
 
@@ -68,6 +109,7 @@ module Swak
68
109
 
69
110
  def Table.transpose(table)
70
111
  raise "Error in Swak::Table.transpose(): Cannot transpose nil table" if table.nil?
112
+ raise "Error in Swak::Table.transpose(): Cannot transpose a SmartRow table (yet)" if table.size > 0 && table[0].is_a?(SmartRow)
71
113
  return [] if table.size == 0
72
114
 
73
115
  num_rows = table.size
@@ -92,5 +134,9 @@ module Swak
92
134
 
93
135
  return out_mat
94
136
  end
137
+
138
+ def Table.column(table, col)
139
+ table.map {|row| row[col]}
140
+ end
95
141
  end
96
142
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: swak
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.4
5
+ version: 0.1.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jesse Rodriguez
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-07-16 00:00:00 Z
13
+ date: 2012-07-22 00:00:00 Z
14
14
  dependencies: []
15
15
 
16
16
  description: Random tools and mixins