lib/iarray.rb in subhash-0.1.2 vs lib/iarray.rb in subhash-0.1.3

- old
+ new

@@ -24,13 +24,16 @@ return 0 if p.length == 0 key = p[0] sp = p.drop(1) - return _lexist_array(sp, key) if key.is_a?(Fixnum) + re, _, opts = _regexp(key) + return _keys_match_lexist(re, [], sp, opts) unless re.nil? - _loop_lexist_array(sp, key) + return _lexist_array(sp, key) if [Fixnum, Range].include?(key.class) + + _loop_lexist_array(p, key) end # Recursive Hash deep level existence # See details at #Hash.rh_exist? def rh_exist?(*p) @@ -52,13 +55,13 @@ sp = p.drop(1) re, res, opts = _regexp(key) return _keys_match(re, res, sp, opts) unless re.nil? - return _get_array(sp, key) if key.is_a?(Fixnum) + return _get_array(sp, key) if [Fixnum, Range].include?(key.class) - _loop_get_array(sp, key) + _loop_get_array(key, p) end # return an exact clone of the recursive Array and Hash contents. # # * *Args* : @@ -187,53 +190,82 @@ # Defines structure feature for Array object. class Array private # Loop in array - def _loop_get_array(sp, key) + def _loop_get_array(key, p) + if key =~ /=\[[0-9]+\.\.[0-9]+\]/ + found = /=\[([0-9]+)\.\.([0-9]+)\]/.match(key) + extract = Range.new(found[1].to_i, found[2].to_i) + sp = p.drop(1) + elsif key =~ /=\[[0-9]+\]/ + extract = /=\[([0-9]+)\]/.match(key)[1].to_i + sp = p.drop(1) + else + sp = p.clone + end + + ret = _loop_array(sp) + + return ret[extract] unless extract.nil? + return ret if ret.length > 0 + nil + end + + def _loop_array(sp) ret = [] each do |e| - next unless e.is_a?(Hash) - next unless e.key?(key) - if sp.length == 0 - ret << e[key] - else - ret << e[key].rh_get(sp) if [Array, Hash].include?(e[key].class) + ret << e + next end + + next unless e.structured? + found = e.rh_get(*sp) + ret << found unless found.nil? end - return ret if ret.length > 0 - nil + ret end - # Index provided. return the value of the index. def _get_array(sp, key) return self[key] if sp.length == 0 - self[key].rh_get(sp) if [Array, Hash].include?(self[key].class) + if key.is_a?(Range) + res = [] + self[key].each do |k| + next unless k.structured? + res << k.rh_get(sp) if k.rh_exist?(sp) + end + res + else + self[key].rh_get(sp) if self[key].structured? + end end + # Check in existing Array, Fixnum and Range data. def _lexist_array(sp, key) - return 0 unless key >= 0 && key < length + return 0 if _key_out_of_array(key) + return 1 if sp.length == 0 - 1 + self[key].rh_lexist?(sp) if [Array, Hash].include?(self[key].class) + 1 + self[key].rh_lexist?(sp) if self[key].structured? end - def _loop_lexist_array(sp, key) + def _key_out_of_array(key) + return !(key >= 0 && key < length) if key.is_a?(Fixnum) + + test = 0..(length - 1) + !(test.include?(key.first) && test.include?(key.last)) + end + + # Check under each array element to get result. + def _loop_lexist_array(p, _key) ret = [] each do |e| - next unless e.is_a?(Hash) - next unless e.key?(key) + next unless e.structured? - if sp.length == 0 - ret << 1 - else - res = 1 - res += e[key].rh_lexist?(sp) if [Array, Hash].include?(e[key].class) - ret << res - end + ret << e.rh_lexist?(*p) end ret.length > 0 ? ret.max : 0 end def _keys_match(re, res, sp, opts) @@ -247,24 +279,50 @@ end return res if empty || res.length > 0 nil end + def _keys_match_lexist(re, res, sp, _opts) + each do |e| + next unless e.is_a?(Hash) + + _keys_match_lexist_hash(re, res, sp, e) + end + return res.max if res.length > 0 + 0 + end + + def _keys_match_lexist_hash(re, res, sp, e) + e.keys.sort.each do |k| + k_re = _key_to_s(k) + next unless re.match(k_re) + + v = 1 + v += e[k].rh_lexist?(sp) if sp.length > 0 && e[k].structured? + res << v + end + end + def _keys_match_hash(re, res, sp, e) e.keys.sort.each do |k| k_re = _key_to_s(k) next unless re.match(k_re) if sp.length == 0 _update_res(res, k, e[k]) else - v = e[k].rh_get(sp) if [Array, Hash].include?(e[k].class) + v = e[k].rh_get(sp) if e[k].structured? _update_res(res, k, v) unless v.nil? end end res end +end + +# Internal function for merge. +class Array + private def _rh_merge(result, data) data = data.clone data_control = _rh_merge_control(data) result_control = _rh_merge_control(result)