Module: SleepingKingStudios::Tools::ArrayTools

Extended by:
ArrayTools
Included in:
ArrayTools
Defined in:
lib/sleeping_king_studios/tools/array_tools.rb

Overview

Tools for working with array-like enumerable objects.

Instance Method Summary collapse

Instance Method Details

#bisect(ary) {|item| ... } ⇒ Array<Array<Object>>

Separates the array into two arrays, the first containing all items in the original array that matches the provided block, and the second containing all items in the original array that do not match the provided block.

Examples:

selected, rejected = ArrayTools.bisect([*0...10]) { |item| item.even? }
selected
#=> [0, 2, 4, 6, 8]
rejected
#=> [1, 3, 5, 7, 9]

Parameters:

  • ary (Array<Object>)

    The array to bisect.

Yield Parameters:

  • item (Object)

    An item in the array to matched.

Yield Returns:

  • (Boolean)

    True if the item matches the criteria, otherwise false.

Returns:

  • (Array<Array<Object>>)

    An array containing two arrays.

Raises:

  • ArgumentError If the first argument is not an Array-like object or if no block is given.



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/sleeping_king_studios/tools/array_tools.rb', line 33

def bisect ary, &block
  require_array! ary

  raise ArgumentError.new('no block given') unless block_given?

  selected, rejected = [], []

  ary.each do |item|
    (yield(item) ? selected : rejected) << item
  end # each

  [selected, rejected]
end

#count_values(ary) ⇒ Hash{Object, Integer} #count_values(ary) {|item| ... } ⇒ Hash{Object, Integer}

Overloads:

  • #count_values(ary) ⇒ Hash{Object, Integer}

    Counts the number of times each value appears in the enumerable object.

    Examples:

    ArrayTools.count_values([1, 1, 1, 2, 2, 3])
    #=> { 1 => 3, 2 => 2, 3 => 1 }
    

    Parameters:

    • ary (Array<Object>)

      The values to count.

    Returns:

    • (Hash{Object, Integer})

      The number of times each value appears in the enumerable object.

    Raises:

    • ArgumentError If the first argument is not an Array-like object.

  • #count_values(ary) {|item| ... } ⇒ Hash{Object, Integer}

    Calls the block with each item and counts the number of times each result appears.

    Examples:

    ArrayTools.count_values([1, 1, 1, 2, 2, 3]) { |i| i ** 2 }
    #=> { 1 => 3, 4 => 2, 9 => 1 }
    

    Parameters:

    • ary (Array<Object>)

      The values to count.

    Yield Parameters:

    • item (Object)

      An item in the array to matched.

    Returns:

    • (Hash{Object, Integer})

      The number of times each result appears.

    Raises:

    • ArgumentError If the first argument is not an Array-like object.



77
78
79
80
81
82
83
84
85
# File 'lib/sleeping_king_studios/tools/array_tools.rb', line 77

def count_values ary, &block
  require_array! ary

  ary.each.with_object({}) do |item, hsh|
    value = block_given? ? block.call(item) : item

    hsh[value] = hsh.fetch(value, 0) + 1
  end # each
end

#deep_dup(ary) ⇒ Array

Creates a deep copy of the object by returning a new Array with deep copies of each array item.

Parameters:

  • ary (Array<Object>)

    The array to copy.

Returns:

  • (Array)

    The copy of the array.



93
94
95
96
97
# File 'lib/sleeping_king_studios/tools/array_tools.rb', line 93

def deep_dup ary
  require_array! ary

  ary.map { |obj| ObjectTools.deep_dup obj }
end

#humanize_list(ary, options = {}) ⇒ String

Accepts a list of values and returns a human-readable string of the values, with the format based on the number of items.

Examples:

With Zero Items

ArrayTools.humanize_list([])
#=> ''

With One Item

ArrayTools.humanize_list(['spam'])
#=> 'spam'

With Two Items

ArrayTools.humanize_list(['spam', 'eggs'])
#=> 'spam and eggs'

With Three Or More Items

ArrayTools.humanize_list(['spam', 'eggs', 'bacon', 'spam'])
#=> 'spam, eggs, bacon, and spam'

With Three Or More Items And Options

ArrayTools.humanize_list(['spam', 'eggs', 'bacon', 'spam'], :last_separator => ' or ')
#=> 'spam, eggs, bacon, or spam'

Parameters:

  • ary (Array<String>)

    The list of values to format. Will be coerced to strings using #to_s.

  • options (Hash) (defaults to: {})

    Optional configuration hash.

Options Hash (options):

  • :last_separator (String)

    The value to use to separate the final pair of values. Defaults to “ and ” (note the leading and trailing spaces). Will be combined with the :separator for lists of length 3 or greater.

  • :separator (String)

    The value to use to separate pairs of values before the last in lists of length 3 or greater. Defaults to “, ” (note the trailing space).

Returns:

  • (String)

    The formatted string.

Raises:

  • ArgumentError If the first argument is not an Array-like object.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/sleeping_king_studios/tools/array_tools.rb', line 136

def humanize_list ary, options = {}
  require_array! ary

  separator = options.fetch(:separator, ', ')
  last_separator = options.fetch(:last_separator, ' and ')

  case ary.count
  when 0
    ''
  when 1
    ary.first.to_s
  when 2
    "#{ary[0]}#{last_separator}#{ary[1]}"
  else
    if last_separator =~ /\A,?\s*/
      last_separator = last_separator.sub /\A,?\s*/, separator
    else
      last_separator = "#{separator}#{last_separator}"
    end # if-else

    "#{ary[0...-1].join(separator)}#{last_separator}#{ary.last}"
  end # case
end

#splice(ary, start, delete_count, *insert) ⇒ Array<Object>

Accepts an array, a start value, a number of items to delete, and zero or more items to insert at that index. Deletes the specified number of items, then inserts the given items at the index and returns the array of deleted items.

Examples:

Deleting items from an Array

values = %w(katana wakizashi tachi daito shoto)
ArrayTools.splice values, 1, 2
#=> ['wakizashi', 'tachi']
values
#=> ['katana', 'daito', 'shoto']

Inserting items into an Array

values = %w(longsword broadsword claymore)
ArrayTools.splice values, 1, 0, 'zweihänder'
#=> []
values
#=> ['longsword', 'zweihänder', 'broadsword', 'claymore']

Inserting and deleting items

values = %w(shortbow longbow crossbow)
ArrayTools.splice values, 2, 1, 'arbalest', 'chu-ko-nu'
#=> ['crossbow']
values
#=> ['shortbow', 'longbow', 'arbalest', 'chu-ko-nu']

Parameters:

  • ary (Array<Object>)

    The array to splice.

  • start (Integer)

    The starting index to delete or insert values from or into. If negative, counts backward from the end of the array.

  • delete_count (Integer)

    The number of items to delete.

  • insert (Array<Object>)

    The items to insert, if any.

Returns:

  • (Array<Object>)

    The deleted items, or an empty array if no items were deleted.

Raises:

  • ArgumentError If the first argument is not an Array-like object.



196
197
198
199
200
201
202
203
204
205
206
# File 'lib/sleeping_king_studios/tools/array_tools.rb', line 196

def splice ary, start, delete_count, *insert
  require_array! ary

  start   = start < 0 ? start + ary.count : start
  range   = start...(start + delete_count)
  deleted = ary[range]

  ary[range] = insert

  deleted
end