aboutsummaryrefslogtreecommitdiffstats
path: root/lib/array_ext.rb
blob: 438d92ee2c8ee6746e3c519943cb1b3c196b73d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Array

  def order_by(order)
    attribute, direction = order.first

    self.sort{ |a,b|
      sa, sb = a.send(attribute.to_sym).to_s, b.send(attribute.to_sym).to_s
      if ((sa.downcase <=> sb.downcase) == 0)
      then sa <=> sb
      else
        na, nb = self.class.check_regexp(sa, sb)
        na <=> nb
      end
    }.tap do |items|
      items.reverse! if direction.to_sym == :desc
    end
  end

  private
  # TODO : Puts in a gem this development 
  def self.check_regexp(sa, sb)
    regexp = /(^|\D+)(\d+|(\D$))/
    ma, mb = multireg(regexp,sa), self.multireg(regexp,sb)
    it = 0
    equal = 0
    ret = ["",""]
    numeric = /(\d+)/
    while (it < [ma.size,mb.size].min) and (equal==0) 
      if (ma[it] and mb[it]) and (ma[it][1] and mb[it][1]) \
        and (numeric.match ma[it][0] and numeric.match mb[it][0])
        l = [ma[it][2].size,mb[it][2].size].max
        ret = [self.format(ma[it], l), self.format(mb[it], l)]
      else 
        ret = [ma[it][0].downcase, mb[it][0].downcase]
      end
      equal = ret[0] <=> ret[1]
      it+=1
    end
    return ret[0], ret[1]
  end

  def self.multireg rgpx, str
    result = []
    while rgpx.match str
      result.push rgpx.match(str)
      str = rgpx.match(str).post_match
    end
    result
  end

  def self.format(match_data, length)
    match_data[1].gsub("_", "").downcase + ("%0#{length}d" % match_data[2].to_i)
  end
end