Add bin and edit workflow
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s

This commit is contained in:
2026-09-16 13:11:16 -06:00
parent c8ac4fcae5
commit 4cee170d66
17576 changed files with 895740 additions and 2 deletions
@@ -0,0 +1,13 @@
## Array#after
require 'facets/array/after'
`Array#after` returns the first value that comes after a given value. The
value after the last is the first. Returns `nil` if the given value is not
in the array.
sequence = ['a', 'b', 'c']
sequence.after('a').assert == 'b'
sequence.after('b').assert == 'c'
sequence.after('c').assert == 'a'
sequence.after('d').assert == nil
@@ -0,0 +1,17 @@
## Array#arrange
require 'facets/array/arrange'
The `arrange` method produces appropriate ranges from the objects in the array.
It assumes inclusive ranges (i.e. `1..4`) and `range.first <= range.last`.
Works with integers, dates and strings. However, all the objects in the array must
be of the same class.
[1,2,3,6,7,8].arrange.assert == [1..3, 6..8]
[10..15, 16..20, 21, 22].arrange.assert == [10..22]
a = %w{a b c g h i j k m o}
a.arrange.assert == ['a'..'c','g'..'k', 'm' , 'o']
@@ -0,0 +1,14 @@
## Array#before
require 'facets/array/before'
Returns the value prior to the given value. The value previous
to the first is the last. Returns nil if the given value is not
in the array.
sequence = ['a', 'b', 'c']
sequence.before('a').assert == 'c'
sequence.before('b').assert == 'a'
sequence.before('c').assert == 'b'
sequence.before('d').assert == nil
@@ -0,0 +1,15 @@
## Array#collapse
require 'facets/array/collapse'
Simplify an array by flattening it then compacting it.
[1,[2,nil,[3]],nil,4].collapse.assert == [1,2,3,4]
## Array#collapse!
Simplify an array by flattening it in place then compacting it in place.
a = [1, nil, [1, 2], nil, [[3]]]
a.collapse!
a.assert == [1, 1, 2, 3]
@@ -0,0 +1,30 @@
## Array#collisions
_alias for Array#commonality_.
require 'facets/array/collisions'
Get a list of all items that have something in common in terms of the
supplied block. If no block is given objects are considered to be in
common if they return the same value for Object#hash and if obj1 == obj2.
This can be useful, for instance, in determining all persons that share
their last name with another person.
Person = Struct.new(:name)
persons = %w{Wayne Pennyworth Grayson Wayne Pennyworth}.map{|n| Person.new(n)}
persons.collisions { |person| person.name }.keys.assert == ["Wayne","Pennyworth"]
The method is similar to #group_by which is a standard Ruby method as of 1.9.
To get effectively the same results with #group_by use `select{ |k,v| v.size > 1 }`.
expected = { 2 => [2, 2], 4 => [4, 4] }
[1, 2, 2, 3, 4, 4].group_by{ |e| e }.
select{ |k,v| v.size > 1 }.assert == expected
[1, 2, 2, 3, 4, 4].collisions.assert == expected
%w{foo bar baz}.collisions{|str| str[0]}.assert == {'b' =>["bar", "baz"] }
Returns a Hash mapping common attribute to those elements.
@@ -0,0 +1,31 @@
## Array#commonality
require 'facets/array/commonality'
Get a list of all items that have something in common in terms of the
supplied block. If no block is given objects are considered to be in
common if they return the same value for Object#hash and if obj1 == obj2.
This can be useful, for instance, in determining all persons that share
their last name with another person.
Person = Struct.new(:name)
persons = %w{Wayne Pennyworth Grayson Wayne Pennyworth}.map{|n| Person.new(n)}
persons.commonality { |person| person.name }.keys # => ["Wayne","Pennyworth"]
The method is similar to #group_by which is a standard Ruby method as of 1.9.
To get effectively the same results with #group_by use `select{ |k,v| v.size > 1 }`.
expected = { 2 => [2, 2], 4 => [4, 4] }
[1, 2, 2, 3, 4, 4].group_by{ |e| e }.
select{ |k,v| v.size > 1 }.assert == expected
[1, 2, 2, 3, 4, 4].commonality.assert == expected
%w{foo bar baz}.commonality{|str| str[0]}.assert == {'b' =>["bar", "baz"] }
Returns a Hash mapping common attribute to those elements.
@@ -0,0 +1,47 @@
## Array#conjoin
require 'facets/array/conjoin'
This is more advanced form of #join. It allows for fine control
of separators.
NOTE: The old version used to default its separator to ", " and
default the terminating separator to " and ". This is no longer
the case. You must specifically provide these parameters.
If no parameters are given, it acts like #join but will a space
separator.
[1,2,3].conjoin.assert == "1 2 3"
Use comma+space and 'and' on tail.
[1,2,3].conjoin(', ', ' and ').assert == "1, 2 and 3"
Use comma+space and 'or' on tail using :last option.
[1,2,3].conjoin(', ', :last => ' or ').assert == "1, 2 or 3"
Use semicolon+space and ampersand on tail using index.
[1,2,3].conjoin('; ', -1 => ' & ').assert == "1; 2 & 3"
Can take a block to determine separator.
[1,2,3,4].conjoin{ |i, a, b| i % 2 == 0 ? '.' : '-' }.assert == "1.2-3.4"
This makes very esoteric transformation possible.
[1,1,2,2].conjoin{ |i, a, b| a == b ? '=' : ' != ' }.assert == "1=1 != 2=2"
[1,2,3,4].conjoin{ |i, x, y| "<#{i} #{x} #{y}>" }.assert == "1<0 1 2>2<1 2 3>3<2 3 4>4"
There are also spacing options. Providing the :space option
pads the separators.
[1,2,3].conjoin(',', '&', :space=>2).assert == "1 , 2 & 3"
And the :spacer option can set an alternate spacing string.
[1,2,3].conjoin('|', '>', :space=>2, :spacer=>'-').assert == "1--|--2-->--3"
@@ -0,0 +1,9 @@
## Array#contains?
_alias of Array#include? _
require 'facets/array/contains'
[1,2,3,4].assert.contains?(2)
[1,2,3,4].refute.contains?(9)
@@ -0,0 +1,13 @@
## Array#delete_unless
require 'facets/array/delete_unless'
The method `#delete_unless` is the inverse of `#delete_if`.
a = [1,2,3]
a.delete_unless{ |e| e == 2 }
a.assert == [2]
[1,2,3].delete_unless{ |x| x < 2 }.assert == [1]
[1,2,3].delete_unless(&:even?).assert == [2]
@@ -0,0 +1,10 @@
## Array#delete_values
require 'facets/array/delete_values'
Delete multiple values from array.
a = [1,2,3,4]
a.delete_values(1,2) #=> [1,2]
a #=> [3,4]
@@ -0,0 +1,15 @@
## Array#delete_values_at
require 'facets/array/delete_values_at'
Delete multiple values from array given
indexes or index range.
a = [1,2,3,4]
a.delete_values_at(1,2).assert == [2,3]
a.assert == [1,4]
a = [1,2,3,4]
a.delete_values_at(0..2).assert == [1,2,3]
a.assert == [4]
@@ -0,0 +1,14 @@
## Array#divide
require 'facets/array/divide'
Divide into sub arrays at elemetns matching given pattern
r = ['a1','b1','a2','b2'].divide(/^a/)
r.assert == [['a1','b1'],['a2','b2']]
r = ['a1','b1','a2','b2'].divide(/^b/)
r.assert == [['a1'],['b1','a2'],['b2']]
r = ['a1','b1','a2','b2'].divide(/c/)
r.assert = [['a1','b1','a2','b2']]
@@ -0,0 +1,14 @@
## Array#duplicates
require 'facets/array/duplicates'
Return list of duplicate elements.
[1,1,2,3].duplicates #=> [1]
Return list of those duplicated min times.
[1,1,2,3,2,4,5,4,2].duplicates(3) #=> [2]
@@ -0,0 +1,12 @@
## Array#each_overlap
require 'facets/array/each_overlap'
Iterate over each slice where the last n values of a preceding slice
overlap with the first n values of the following slice. The value of n
is specified by the second `overlap` argument.
a, r = [1,2,3,4,5], []
a.each_overlap(2,1) { |x,y| r << [x,y] }
r.assert == [[1,2],[2,3],[3,4],[4,5]]
@@ -0,0 +1,13 @@
## Array#each_pair
require 'facets/array/each_pair'
Iterate over an array yielding with index and value.
result = {}
a = [:a,:b,:c,:d]
a.each_pair{|i,e| result[e] = i + 1}
result.assert == {a: 1, b: 2, c: 3, d: 4}
*NOTE* this is the inverse of `Array#each_with_index`, and is intended to provide
polymorphism with `Hash#each_pair`.
@@ -0,0 +1,12 @@
## Array#each_value
require 'facets/array/each_value'
This is an alias of Alias#each, and is provided to provide polymorphism with
Hash#each_value.
a = [ "a", "b", "c" ]
out = ''
a.each_value {|x| out += "#{x} -- " }
out.assert == 'a -- b -- c -- '
@@ -0,0 +1,13 @@
## Array#entropy
require 'facets/array/entropy'
Shannon's entropy for an array - returns the average
bits per symbol required to encode the array.
Lower values mean less "entropy" - i.e. less unique
information in the array.
e = %w{ a b c d e e e }.entropy
("%.3f" % e) #=> "2.128"
@@ -0,0 +1,13 @@
## Array#extract_options!
require 'facets/array/extract_options'
Extracts options from a set of arguments. Removes and returns the last
element in the array if it's a hash, otherwise returns a blank hash.
def options(*args)
args.extract_options!
end
options(1, 2).assert == {}
options(1, 2, :a => :b).assert == {:a=>:b}
@@ -0,0 +1,11 @@
## Array#first!
require 'facets/array/indexable'
Alias for shift, which removes and returns the first element in an array
a = ['a','y','z']
a.first!.assert == 'a'
a.assert ['y','z']
@@ -0,0 +1,11 @@
## Array#thru
require 'facets/array/from'
Returns elements from index i until the end.
%w{W o r l d}.from(3).assert == %w{l d}
Returns entire array for i > length
%w{W o r l d}.from(7).assert == nil
@@ -0,0 +1,11 @@
## Array#ideal_entropy
require 'facets/array/entropy'
Returns the maximum possible Shannon entropy of the array
with given size assuming that it is an "order-0" source
(each element is selected independently of the next).
%w{ a b }.ideal_entropy.assert == 1.0
%w{ a a b b }.ideal_entropy.assert == 2.0
@@ -0,0 +1,11 @@
## Array#intersection
require 'facets/array/intersection'
Returns the values in common for an array set (nil, single value/object, or range).
[1,2].intersection.assert == nil
[1..10,11..20].intersection.assert == nil
[10,1..10].intersection.assert == 10
[1..10,5,5..8,4..8].intersection.assert == 5
[1..10, 5..8, 5..10 ].intersection.assert == (5..8)
@@ -0,0 +1,11 @@
## Array#last!
require 'facets/array/indexable'
Alias for pop, which removes and returns the last element in an
array.
a = [1,2,3]
a.last!.assert == 3
a.assert == [1,2]
@@ -0,0 +1,23 @@
# Array#median
require 'facets/array/median'
Determines the _sorted_ middle element.
a = %w{a a b b c c c}
a.median #=> "b"
When there are an even number of elements, the greater
of the two middle elements is given.
a = %w{a a b b c c c d}
a.median #=> "c"
An offset can be supplied to get an element relative
to the middle.
a = %w{a a b b c c c d}
a.median(-1) #=> "b"
The the array is empty, +nil+ is returned.
@@ -0,0 +1,15 @@
## Array#merge
require 'facets/array/merge'
a = [1,2,3]
b = [3,4,5]
a.merge(b).assert == [1,2,3,4,5]
## Array#merge!
a = [1,2,3]
b = [3,4,5]
a.merge!(b)
a.assert == [1,2,3,4,5]
@@ -0,0 +1,10 @@
## Array#missing
require 'facets/array/missing'
Determine the 'holes' in the values of an array. Returns the missing elements
in an array set.
[1,3..3].missing.assert == [2]
[1..5,10..12].missing.assert == [6..9]
[100, 9..11, 14, 1..5, 16, 10..12, 17..17].missing.assert == [6..8, 13, 15, 18..99]
@@ -0,0 +1,9 @@
## Array#mode
require 'facets/array/mode'
In Statistics, mode is the value that occurs most frequently in a given set of
data. This method returns an array in case there is a tie.
[1, 1, 2, 3].mode.assert == [1]
[1, 1, 2, 2, 3].mode.assert == [1,2]
@@ -0,0 +1,16 @@
## Array#nonuniq
require 'facets/array/nonuniq'
Returns a list of non uniq elements.
a = [1, 1, 2, 2, 3, 4, 5]
a.nonuniq.sort.assert == [1, 2]
## Array#nonuniq!
Same as #nonuniq but acts in place.
a = [1, 1, 2, 2, 3, 4, 5]
a.nonuniq!
a.sort.assert == [1,2]
@@ -0,0 +1,8 @@
## Array#not_empty?
require 'facets/array/not_empty'
Array is not empty?
[1,2].assert.not_empty?
[].refute.not_empty?
@@ -0,0 +1,18 @@
## Array#occur
require 'facets/array/occur'
Returns a list of elements that occur +n+ times.
If +n+ is a Range then returns elements that occur a number
of time within the range.
a = [:a,:b,:a]
a.occur(1).assert == [:b]
a.occur(2).assert == [:a]
a = [:a,:b,:a]
a.occur(1..2).assert == [:a,:b]
a = [:a,:b,:a]
a.occur{ |n| n % 2 == 0 }.assert == [:a]
@@ -0,0 +1,13 @@
## Array#occurrence
require 'facets/array/occurrence'
Create a hash of each uniq element of the array
and how many time each appears.
r = [:a,:a,:b,:c,:c,:c].occurrence
r.assert == { :a => 2, :b => 1, :c => 3 }
r = [2,2,3,4,4,4].occurrence{|i| i % 2}
r.assert == { 0 => 5, 1 => 1 }
@@ -0,0 +1,9 @@
## Array#only
require 'facets/array/only'
[5].only.assert == 5
[nil].only.assert == nil
expect(IndexError){ [].only }
expect(IndexError){ [1,2,3].only }
@@ -0,0 +1,10 @@
## Array#**
require 'facets/array/op_pow'
Alias for Array#product
NOTE: This method is not a common core extension and is not loaded automatically
when using ```require 'facets'```
([1,2] ** [3,4]).assert == [[1, 3], [1, 4], [2, 3], [2, 4]]
@@ -0,0 +1,28 @@
## Array#pad
require 'facets/array/pad'
r = [0,1,2,3].pad(7,"x")
x = [0,1,2,3,"x","x","x"]
r.assert == x
negative index
r = [0,1,2,3].pad(-7,"n")
x = ["n","n","n",0,1,2,3]
r.assert == x
## Array#pad!
a = [0,1,2,3]
r = a.pad!(6,"y")
x = [0,1,2,3,"y","y"]
r.assert == x
negative index
a = [0,1,2,3]
r = a.pad!(-6,"q")
x = ["q","q",0,1,2,3]
r.assert == x
@@ -0,0 +1,10 @@
## Array#peek
require 'facets/array/peek'
Provide an index to inspect the array from back to front.
[1,2,3].peek .assert == 3
[1,2,3].peek(1) .assert == 2
[1,2,3].peek(-1).assert == 1
@@ -0,0 +1,15 @@
## Array#poke
require 'facets/array/poke'
Put an object on the bottom of the stack (front of the array).
a = [2,3]
a.poke(1)
a.assert == [1,2,3]
Or supply an index and #poke works like insert.
a = [1,3]
a.poke(2,1)
a.assert == [1,2,3]
@@ -0,0 +1,8 @@
## Array#probability
require 'facets/array/probability'
Generates a hash mapping each unique element in the array to the relative
frequency, i.e. the probability, of it's appearance.
[:a, :b, :c, :c].probability.assert == {a: 0.25, b: 0.25, c: 0.50}
@@ -0,0 +1,10 @@
## Array#pull
require 'facets/array/pull'
Alias for Array#shift which removes an object off the first slot of an array.
This is the opposite of pop.
a = [1,2,3]
a.pull.assert == 1
a.assert == [2,3]
@@ -0,0 +1,10 @@
## Array#recurse
require 'facets/array/recurse'
Apply a block to array, and recursively apply that block to each sub-array
or +type+.
a = ["a", ["b", "c", nil], nil]
r = a.recurse{|a| a.compact!}
r.assert == ["a", ["b", "c"]]
@@ -0,0 +1,20 @@
## Array#recursively
require 'facets/array/recursively'
Apply a method to array, and recursively apply that method to each sub-array
or given +types+.
By default the sub-types are passed through unaffected. Passing a block
to #recursively can be used to change this.
each
r = []
[1,2,['a','b'], 3].recursively.each{|v| r << v}
r.assert = [1,2,'a','b', 3]
map
arr = ['foo','bar',['a','b']]
arr.recursively.map{|v| v.to_sym}.assert == [:foo,:bar,[:a,:b]]
@@ -0,0 +1,10 @@
## Array#reject_values
require 'facets/array/reject_values'
Non-destructive form of Array#delete_values. Unlike delete_values this method
returns a new array.
a = [1,2,3,4,5]
a.reject_values(2,4).assert == [1,3,5]
a.assert [1,2,3,4,5]
@@ -0,0 +1,14 @@
## Array#splice
require 'facets/array/splice'
Splice acts as a combination of #slice! and #store. If one argument is given it
calls #slice!, if two are given it calls #store.
a = [1,2,3]
a.splice(1).assert == 2
a.assert == [1,3]
b = [1,2,3]
b.splice(1,4).assert == 4
b.assert == [1,4,3]
@@ -0,0 +1,13 @@
## Array#split
require 'facets/array/split'
Split on matching pattern. Unlike #divide, this does not include matching
elements.
['a','b','c'].split('b').assert == [['a'],['c']]
a = ['a1','a2','b1','a3','b2','a4']
a.split(/^b/).assert == [['a1','a2'],['a3'],['a4']]
@@ -0,0 +1,14 @@
## Array#squeeze!
require 'facets/array/squeeze'
Destructive version of Enumerable#squeeze.
a = [1,2,2,3,3,2,1]
a.squeeze!
a.assert == [1,2,3,2,1]
a = [1,2,2,3,3,2,1]
a.squeeze!(3)
a.assert == [1,2,2,3,2,1]
@@ -0,0 +1,16 @@
## Array#step
require 'facets/array/step'
Iterate over every nth element of an array. Without a block, it returns an
Enumerator.
r = []
[:a, :b, :c, :d].step(2) { |x| r << x }
r.assert == [:b, :d]
[:a, :b, :c, :d].step(1).to_a.assert == [:a, :b, :c, :d]
[:a, :b, :c, :d].step(2).to_a.assert == [:b, :d]
[:a, :b, :c, :d].step(3).to_a.assert == [:c]
[:a, :b, :c, :d].step(4).to_a.assert == [:d]
[:a, :b, :c, :d].step(5).to_a.assert == []
@@ -0,0 +1,9 @@
## Array#store
require 'facets/array/store'
Store a value at a given index. Store is an alias for #[]=
a = []
a.store(1,"A")
a[1].assert == "A"
@@ -0,0 +1,12 @@
## Array#thru
require 'facets/array/thru'
Fetch Values from a start index thru an end index.
[1,2,3,4,5].thru(0,2) #=> [1,2,3]
[1,2,3,4,5].thru(2,4) #=> [3,4,5]
[1,2,3,4,5].thru(2) #=> [1,2,3]
[1,2,3,4,5].thru(4) #=> [1,2,3,4,5]
@@ -0,0 +1,11 @@
## Array#to_h
require 'facets/array/to_h'
Convert an associative array to a Hash. Each element of the associative array
should be a 1 or 2 element array
Note this is built into ruby as of 2.1.0
arr = [[:a, 1], [:b, 2]]
arr.to_h.assert == {:a => 1, :b => 2}
@@ -0,0 +1,20 @@
## Array#traverse
require 'facets/array/traverse'
Construct a new array created by traversing the array and its sub-arrays,
executing the given block on the elements.
h = ['A', 'B', ['X', 'Y']]
g = h.traverse{ |e| e.downcase }
g.assert = ['a','b',['x', 'y']]
## Array#traverse!
Like #traverse, but will change the array in place.
h = ['A', 'B', ['X', 'Y']]
h.traverse!{ |e| e.downcase }
h.assert = ['a','b',['x', 'y']]
@@ -0,0 +1,16 @@
## Array#uniq_by!
require 'facets/array/uniq_by'
Like #uniq, but determines uniqueness based on a given block.
As can be seen from the examples, order is significant.
r = (-5..5).to_a
r.uniq_by!{ |i| i*i }
r.assert == [-5, -4, -3, -2, -1, 0]
r = (-5..5).to_a.reverse
r.uniq_by!{ |i| i*i }
r.assert == [5, 4, 3, 2, 1, 0]
@@ -0,0 +1,14 @@
## Array#unique_permutation
require 'facets/array/unique_permutation'
Enumerates permutation of Array. Unlike Array#permutation, there are no
duplicates in generated permutations. Instead elements must be comparable
p = [1,1,2,2,3].unique_permutation(2).to_a
e = [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2]]
p.assert == e
[1,1,2,3].unique_permutation.to_a.assert != [1,1,2,3].permutation.to_a
[1,1,2,3].unique_permutation.to_a.assert == [1,1,2,3].permutation.to_a.uniq
@@ -0,0 +1,8 @@
## Array::zip
require 'facets/array/zip'
Class level rendition of Array#zip
Array.zip([1,2], [3,4]).assert == [[1,3],[2,4]]