- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/mrblib/array.rb
r331 r439 1 1 class Array 2 ##3 # call-seq:4 # Array.try_convert(obj) -> array or nil5 #6 # Tries to convert +obj+ into an array, using +to_ary+ method.7 # converted array or +nil+ if +obj+ cannot be converted for any reason.8 # This method can be used to check if an argument is an array.9 #10 # Array.try_convert([1]) #=> [1]11 # Array.try_convert("1") #=> nil12 #13 # if tmp = Array.try_convert(arg)14 # # the argument is an array15 # elsif tmp = String.try_convert(arg)16 # # the argument is a string17 # end18 #19 def self.try_convert(obj)20 if obj.respond_to?(:to_ary)21 obj.to_ary22 else23 nil24 end25 end26 27 2 ## 28 3 # call-seq: … … 42 17 # 43 18 def uniq!(&block) 44 ary = self.dup 45 result = [] 19 hash = {} 46 20 if block 21 self.each do |val| 22 key = block.call(val) 23 hash[key] = val unless hash.key?(key) 24 end 25 result = hash.values 26 else 47 27 hash = {} 48 while ary.size > 0 49 val = ary.shift 50 key = block.call(val) 51 hash[key] = val unless hash.has_key?(key) 52 end 53 hash.each_value do |value| 54 result << value 55 end 56 else 57 while ary.size > 0 58 result << ary.shift 59 ary.delete(result.last) 60 end 28 self.each do |val| 29 hash[val] = val 30 end 31 result = hash.keys 61 32 end 62 33 if result.size == self.size … … 82 53 def uniq(&block) 83 54 ary = self.dup 84 if block 85 ary.uniq!(&block) 86 else 87 ary.uniq! 88 end 55 ary.uniq!(&block) 89 56 ary 90 57 end … … 106 73 hash = {} 107 74 array = [] 108 elem.each { |x| hash[x] = true } 109 self.each { |x| array << x unless hash[x] } 75 idx = 0 76 len = elem.size 77 while idx < len 78 hash[elem[idx]] = true 79 idx += 1 80 end 81 idx = 0 82 len = size 83 while idx < len 84 v = self[idx] 85 array << v unless hash[v] 86 idx += 1 87 end 110 88 array 89 end 90 91 ## 92 # call-seq: 93 # ary.difference(other_ary1, other_ary2, ...) -> new_ary 94 # 95 # Returns a new array that is a copy of the original array, removing all 96 # occurrences of any item that also appear in +other_ary+. The order is 97 # preserved from the original array. 98 # 99 def difference(*args) 100 ary = self 101 args.each do |x| 102 ary = ary - x 103 end 104 ary 111 105 end 112 106 … … 130 124 ## 131 125 # call-seq: 126 # ary.union(other_ary,...) -> new_ary 127 # 128 # Set Union---Returns a new array by joining this array with 129 # <i>other_ary</i>, removing duplicates. 130 # 131 # ["a", "b", "c"].union(["c", "d", "a"], ["a", "c", "e"]) 132 # #=> ["a", "b", "c", "d", "e"] 133 # 134 def union(*args) 135 ary = self.dup 136 args.each do |x| 137 ary.concat(x) 138 ary.uniq! 139 end 140 ary 141 end 142 143 ## 144 # call-seq: 132 145 # ary & other_ary -> new_ary 133 146 # … … 142 155 hash = {} 143 156 array = [] 144 elem.each{|v| hash[v] = true } 145 self.each do |v| 157 idx = 0 158 len = elem.size 159 while idx < len 160 hash[elem[idx]] = true 161 idx += 1 162 end 163 idx = 0 164 len = size 165 while idx < len 166 v = self[idx] 146 167 if hash[v] 147 168 array << v 148 169 hash.delete v 149 170 end 171 idx += 1 150 172 end 151 173 array 174 end 175 176 ## 177 # call-seq: 178 # ary.intersection(other_ary,...) -> new_ary 179 # 180 # Set Intersection---Returns a new array containing elements common to 181 # this array and <i>other_ary</i>s, removing duplicates. The order is 182 # preserved from the original array. 183 # 184 # [1, 2, 3].intersection([3, 4, 1], [1, 3, 5]) #=> [1, 3] 185 # 186 def intersection(*args) 187 ary = self 188 args.each do |x| 189 ary = ary & x 190 end 191 ary 152 192 end 153 193 … … 170 210 # 171 211 def flatten(depth=nil) 172 ar = [] 173 self.each do |e| 174 if e.is_a?(Array) && (depth.nil? || depth > 0) 175 ar += e.flatten(depth.nil? ? nil : depth - 1) 176 else 177 ar << e 178 end 179 end 180 ar 212 res = dup 213 res.flatten! depth 214 res 181 215 end 182 216 … … 201 235 modified = false 202 236 ar = [] 203 self.each do |e| 237 idx = 0 238 len = size 239 while idx < len 240 e = self[idx] 204 241 if e.is_a?(Array) && (depth.nil? || depth > 0) 205 242 ar += e.flatten(depth.nil? ? nil : depth - 1) … … 208 245 ar << e 209 246 end 247 idx += 1 210 248 end 211 249 if modified … … 253 291 # for efficiency 254 292 def reverse_each(&block) 255 return to_enum :reverse_each unless block _given?293 return to_enum :reverse_each unless block 256 294 257 295 i = self.size - 1 … … 263 301 end 264 302 265 NONE=Object.new266 303 ## 267 304 # call-seq: … … 288 325 # 289 326 290 def fetch(n =nil, ifnone=NONE, &block)327 def fetch(n, ifnone=NONE, &block) 291 328 warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block 292 329 … … 475 512 476 513 def delete_if(&block) 477 return to_enum :delete_if unless block _given?514 return to_enum :delete_if unless block 478 515 479 516 idx = 0 … … 504 541 505 542 def reject!(&block) 506 return to_enum :reject! unless block _given?543 return to_enum :reject! unless block 507 544 508 545 len = self.size … … 594 631 595 632 def bsearch(&block) 596 return to_enum :bsearch unless block_given? 633 return to_enum :bsearch unless block 634 635 if idx = bsearch_index(&block) 636 self[idx] 637 else 638 nil 639 end 640 end 641 642 ## 643 # call-seq: 644 # ary.bsearch_index {|x| block } -> int or nil 645 # 646 # By using binary search, finds an index of a value from this array which 647 # meets the given condition in O(log n) where n is the size of the array. 648 # 649 # It supports two modes, depending on the nature of the block and they are 650 # exactly the same as in the case of #bsearch method with the only difference 651 # being that this method returns the index of the element instead of the 652 # element itself. For more details consult the documentation for #bsearch. 653 654 def bsearch_index(&block) 655 return to_enum :bsearch_index unless block 597 656 598 657 low = 0 599 high = s elf.size658 high = size 600 659 satisfied = false 660 601 661 while low < high 602 mid = low + ((high - low) / 2).truncate 603 val = self[mid] 604 v = block.call(val) 605 if v.is_a?(Integer) 606 return val if v == 0 607 smaller = v < 0 608 elsif v == true 662 mid = ((low+high)/2).truncate 663 res = block.call self[mid] 664 665 case res 666 when 0 # find-any mode: Found! 667 return mid 668 when Numeric # find-any mode: Continue... 669 in_lower_half = res < 0 670 when true # find-min mode 671 in_lower_half = true 609 672 satisfied = true 610 smaller = true 611 elsif v == false || v.nil? 612 smaller = false 613 end 614 if smaller 673 when false, nil # find-min mode 674 in_lower_half = false 675 else 676 raise TypeError, 'invalid block result (must be numeric, true, false or nil)' 677 end 678 679 if in_lower_half 615 680 high = mid 616 681 else … … 618 683 end 619 684 end 620 return nil if low == self.size 621 return nil unless satisfied 622 self[low] 623 end 624 625 ## 626 # call-seq: 627 # ary.delete_if { |item| block } -> ary 628 # ary.delete_if -> Enumerator 629 # 630 # Deletes every element of +self+ for which block evaluates to +true+. 631 # 632 # The array is changed instantly every time the block is called, not after 633 # the iteration is over. 634 # 635 # See also Array#reject! 636 # 637 # If no block is given, an Enumerator is returned instead. 638 # 639 # scores = [ 97, 42, 75 ] 640 # scores.delete_if {|score| score < 80 } #=> [97] 641 642 def delete_if(&block) 643 return to_enum :delete_if unless block_given? 644 645 idx = 0 646 while idx < self.size do 647 if block.call(self[idx]) 648 self.delete_at(idx) 649 else 650 idx += 1 651 end 652 end 653 self 685 686 satisfied ? low : nil 654 687 end 655 688 … … 670 703 671 704 def keep_if(&block) 672 return to_enum :keep_if unless block _given?705 return to_enum :keep_if unless block 673 706 674 707 idx = 0 … … 699 732 700 733 def select!(&block) 701 return to_enum :select! unless block _given?734 return to_enum :select! unless block 702 735 703 736 result = [] 704 self.each do |x| 705 result << x if block.call(x) 706 end 707 return nil if self.size == result.size 737 idx = 0 738 len = size 739 while idx < len 740 elem = self[idx] 741 result << elem if block.call(elem) 742 idx += 1 743 end 744 return nil if len == result.size 708 745 self.replace(result) 709 746 end … … 727 764 if block 728 765 idx = 0 729 self.each do |*e| 730 return idx if block.call(*e) 766 len = size 767 while idx < len 768 return idx if block.call self[idx] 731 769 idx += 1 732 770 end … … 735 773 end 736 774 nil 737 end738 739 ##740 # call-seq:741 # ary.to_ary -> ary742 #743 # Returns +self+.744 #745 def to_ary746 self747 775 end 748 776 … … 763 791 end 764 792 end 793 794 ## 795 # call-seq: 796 # ary.permutation { |p| block } -> ary 797 # ary.permutation -> Enumerator 798 # ary.permutation(n) { |p| block } -> ary 799 # ary.permutation(n) -> Enumerator 800 # 801 # When invoked with a block, yield all permutations of length +n+ of the 802 # elements of the array, then return the array itself. 803 # 804 # If +n+ is not specified, yield all permutations of all elements. 805 # 806 # The implementation makes no guarantees about the order in which the 807 # permutations are yielded. 808 # 809 # If no block is given, an Enumerator is returned instead. 810 # 811 # Examples: 812 # 813 # a = [1, 2, 3] 814 # a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 815 # a.permutation(1).to_a #=> [[1],[2],[3]] 816 # a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] 817 # a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 818 # a.permutation(0).to_a #=> [[]] # one permutation of length 0 819 # a.permutation(4).to_a #=> [] # no permutations of length 4 820 def permutation(n=self.size, &block) 821 return to_enum(:permutation, n) unless block 822 size = self.size 823 if n == 0 824 yield [] 825 elsif 0 < n && n <= size 826 i = 0 827 while i<size 828 result = [self[i]] 829 if n-1 > 0 830 ary = self[0...i] + self[i+1..-1] 831 ary.permutation(n-1) do |c| 832 yield result + c 833 end 834 else 835 yield result 836 end 837 i += 1 838 end 839 end 840 self 841 end 842 843 ## 844 # call-seq: 845 # ary.combination(n) { |c| block } -> ary 846 # ary.combination(n) -> Enumerator 847 # 848 # When invoked with a block, yields all combinations of length +n+ of elements 849 # from the array and then returns the array itself. 850 # 851 # The implementation makes no guarantees about the order in which the 852 # combinations are yielded. 853 # 854 # If no block is given, an Enumerator is returned instead. 855 # 856 # Examples: 857 # 858 # a = [1, 2, 3, 4] 859 # a.combination(1).to_a #=> [[1],[2],[3],[4]] 860 # a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] 861 # a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]] 862 # a.combination(4).to_a #=> [[1,2,3,4]] 863 # a.combination(0).to_a #=> [[]] # one combination of length 0 864 # a.combination(5).to_a #=> [] # no combinations of length 5 865 866 def combination(n, &block) 867 return to_enum(:combination, n) unless block 868 size = self.size 869 if n == 0 870 yield [] 871 elsif n == 1 872 i = 0 873 while i<size 874 yield [self[i]] 875 i += 1 876 end 877 elsif n <= size 878 i = 0 879 while i<size 880 result = [self[i]] 881 self[i+1..-1].combination(n-1) do |c| 882 yield result + c 883 end 884 i += 1 885 end 886 end 887 self 888 end 889 890 ## 891 # call-seq: 892 # ary.transpose -> new_ary 893 # 894 # Assumes that self is an array of arrays and transposes the rows and columns. 895 # 896 # If the length of the subarrays don't match, an IndexError is raised. 897 # 898 # Examples: 899 # 900 # a = [[1,2], [3,4], [5,6]] 901 # a.transpose #=> [[1, 3, 5], [2, 4, 6]] 902 903 def transpose 904 return [] if empty? 905 906 column_count = nil 907 self.each do |row| 908 raise TypeError unless row.is_a?(Array) 909 column_count ||= row.size 910 raise IndexError, 'element size differs' unless column_count == row.size 911 end 912 913 Array.new(column_count) do |column_index| 914 self.map { |row| row[column_index] } 915 end 916 end 917 918 ## 919 # call-seq: 920 # ary.to_h -> Hash 921 # ary.to_h{|item| ... } -> Hash 922 # 923 # Returns the result of interpreting <i>aray</i> as an array of 924 # <tt>[key, value]</tt> pairs. If a block is given, it should 925 # return <tt>[key, value]</tt> pairs to construct a hash. 926 # 927 # [[:foo, :bar], [1, 2]].to_h 928 # # => {:foo => :bar, 1 => 2} 929 # [1, 2].to_h{|x| [x, x*2]} 930 # # => {1 => 2, 2 => 4} 931 # 932 def to_h(&blk) 933 h = {} 934 self.each do |v| 935 v = blk.call(v) if blk 936 raise TypeError, "wrong element type #{v.class}" unless Array === v 937 raise ArgumentError, "wrong array length (expected 2, was #{v.length})" unless v.length == 2 938 h[v[0]] = v[1] 939 end 940 h 941 end 942 943 alias append push 944 alias prepend unshift 945 alias filter! select! 765 946 end
Note:
See TracChangeset
for help on using the changeset viewer.