array_include_methods 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 201b9e696a4644180df82e669767d5a83cd626dc9863ba7451d22707c53b20ba
4
- data.tar.gz: b3920beaa33a19dedf9430eca869400cf763d0ddc0a28005550a7ea569c953e6
3
+ metadata.gz: cdce8ec8eb451f28c665c7dd6833190699abc55358dd2f488cfe594565ea2d54
4
+ data.tar.gz: bdd5b90776e4a606a161ec8b62fc5e9f1b6d7c3f03c12e77b8e7235907a5a7fb
5
5
  SHA512:
6
- metadata.gz: '00929ce43674a96779a5a08c43357fcd0e4708782586a732f9040f6981c70858a80971f101a61a22b1d6de3e0e7a36d8d585d318f66370f040535443ea3ac04a'
7
- data.tar.gz: d71713c34a7adad5d900342273666c99388b0c5e2b8cff0f3a45071c07809664bc904fd0d68576d322361b0e29dd118ae22076d7272fc7cb57379b72a43ae270
6
+ metadata.gz: 96e1cd8df937ded36f613d0fb97d1b1afc98ce44cc13900dfa7599ba0e6289b2119d4df51143145e6d177178fe40e4e72daa0395fad7dfa93e101518fb6740d6
7
+ data.tar.gz: 6d5b550e3acc6c8f2bea70553960a5e1bdf720d87b1603ad58c70bf8d5da53f383b07d10bdc68fd80d51fcdfbf2ae652426b1b3454b0101540c1499309e88e50
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.5.1
4
+
5
+ - `counts` returns a hash of counts of every element in the array, performed in linear time (running time of O(n)).
6
+ - `duplicates` returns a single occurrence of all elements that repeated in an array
7
+ - `array_difference_indices`/`array_difference_indexes` aliases for `array_diff_indices`/`array_diff_indexes`
8
+ - `array_diff`/`array_difference` (return elements of `array_diff_indexes`)
9
+ - `array_intersection` (returns elements of `array_intersection_indexes`)
10
+
11
+ ## 1.5.0
12
+
13
+ - Add RubyMotion compatibility
14
+ - Ensure Opal compatibility happens through RUBY_ENGINE instead of RUBY_PLATFORM
15
+
3
16
  ## 1.4.0
4
17
 
5
18
  - `array_diff_indexes(other_array)` (alias: `array_diff_indices`)
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 Andy Maleh
1
+ Copyright (c) 2020-2022 Andy Maleh
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # ArrayIncludeMethods 1.4.0 - Ruby Refinement
1
+ # ArrayIncludeMethods 1.5.1 - [Ruby Refinement](https://docs.ruby-lang.org/en/master/syntax/refinements_rdoc.html)
2
2
  [![Gem Version](https://badge.fury.io/rb/array_include_methods.svg)](http://badge.fury.io/rb/array_include_methods)
3
3
  [![Build Status](https://travis-ci.com/AndyObtiva/array_include_methods.svg?branch=master)](https://travis-ci.com/AndyObtiva/array_include_methods)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/array_include_methods/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/array_include_methods?branch=master)
5
5
 
6
- `Array#include_all?` & `Array#include_any?` methods missing from basic Ruby `Array` API.
6
+ `Array#include_all?`, `Array#include_any?`, `Array#include_array?`, `Array#array_index`, `Array#counts`, and `Array#duplicates` methods missing from basic Ruby `Array` API.
7
7
 
8
8
  ## Setup
9
9
 
@@ -12,7 +12,7 @@
12
12
  Include the following in Gemfile:
13
13
 
14
14
  ```ruby
15
- gem 'array_include_methods', '~> 1.4.0'
15
+ gem 'array_include_methods', '~> 1.5.1'
16
16
  ```
17
17
 
18
18
  Run:
@@ -26,7 +26,7 @@ bundle
26
26
  Run:
27
27
 
28
28
  ```
29
- gem install array_include_methods -v1.4.0
29
+ gem install array_include_methods -v1.5.1
30
30
  ```
31
31
 
32
32
  ## Usage
@@ -37,13 +37,13 @@ Add the following line to your application if you are not requiring all gems via
37
37
  require 'array_include_methods'
38
38
  ```
39
39
 
40
- To activate the `ArrayIncludeMethods` Ruby Refinement for the `Array` class, add the following line to every Ruby file that needs it:
40
+ To activate the `ArrayIncludeMethods` [Ruby Refinement](https://docs.ruby-lang.org/en/master/syntax/refinements_rdoc.html) for the `Array` class, add the following line to every Ruby file that needs it:
41
41
 
42
42
  ```ruby
43
43
  using ArrayIncludeMethods
44
44
  ```
45
45
 
46
- Now, you have `#include_all?` and `#include_any?` methods on `Array` objects.
46
+ Now, you have `#include_all?`, `#include_any?`, `#include_array?`, `#array_index`, `#array_diff_indices`, and `#array_intersection_indices` methods on `Array` objects.
47
47
 
48
48
  ## Examples
49
49
 
@@ -128,9 +128,43 @@ Returns indexes from `self` array for which elements do not match elements in `o
128
128
  [1, 2, 3, 4].array_diff_indexes(nil) # returns [0, 1, 2, 3]
129
129
  ```
130
130
 
131
+ ### `Array#counts`
132
+
133
+ Returns a hash of counts of every element in the array,
134
+ performed in linear time (running time of O(n)).
135
+
136
+ ```ruby
137
+ [1, 2, 3, 4].counts # returns {1=>1, 2=>1, 3=>1, 4=>1}
138
+ [1, :a, :a, :b, 'bee', 'see', true, true, nil, nil].counts # returns {1=>1, :a=>2, :b=>1, "bee"=>1, "see"=>1, true=>2, nil=>2}
139
+ [1, :a, :a, :b, 'bee', 'see', true, true, nil].counts # {1=>1, :a=>2, :b=>1, "bee"=>1, "see"=>1, true=>2, nil=>1}
140
+ [1, {a: 1}, :a, :a, :b, 'bee', 'see', true, true, {a: 1}, {a: 1}].counts # {1=>1, {:a=>1}=>3, :a=>2, :b=>1, "bee"=>1, "see"=>1, true=>2}
141
+ [].counts # returns {}
142
+ ```
143
+
144
+ ### `Array#duplicates`
145
+
146
+ Returns a single occurrence of all elements that repeated in an array,
147
+ performed in linear time (running time of O(n)).
148
+
149
+ ```ruby
150
+ [1, 2, 3, 4].duplicates # returns []
151
+ [1, :a, :a, :b, 'bee', 'see', true, true, nil, nil].duplicates # returns [:a, true, nil]
152
+ [1, :a, :a, :b, 'bee', 'see', true, true, nil].duplicates # returns [:a, true]
153
+ [1, {a: 1}, :a, :a, :b, 'bee', 'see', true, true, {a: 1}, {a: 1}].duplicates # returns [:a, true, {a: 1}]
154
+ [].duplicates # returns []
155
+ ```
156
+
157
+ ## JRuby Compatibility
158
+
159
+ This gem is 100% compatible with JRuby.
160
+
131
161
  ## Opal Compatibility
132
162
 
133
- This gem degrades gracefully to monkey-patching in [Opal Ruby](https://opalrb.com) and provides a `using` method shim so consumer code does not have to change if it used gems that rely on the Ruby refinement
163
+ This gem degrades gracefully to monkey-patching in [Opal Ruby](https://opalrb.com) and provides a `using` method shim so consumer code does not have to change if it used gems that rely on the [Ruby refinement](https://docs.ruby-lang.org/en/master/syntax/refinements_rdoc.html).
164
+
165
+ ## RubyMotion Compatibility
166
+
167
+ This gem degrades gracefully to monkey-patching in [RubyMotion](http://www.rubymotion.com/) and provides a `using` method shim so consumer code does not have to change if it used gems that rely on the [Ruby refinement](https://docs.ruby-lang.org/en/master/syntax/refinements_rdoc.html).
134
168
 
135
169
  ## TODO
136
170
 
@@ -152,5 +186,6 @@ This gem degrades gracefully to monkey-patching in [Opal Ruby](https://opalrb.co
152
186
 
153
187
  ## Copyright
154
188
 
155
- Copyright (c) 2020 Andy Maleh. See LICENSE.txt for
156
- further details.
189
+ [MIT](LICENSE.txt)
190
+
191
+ Copyright (c) 2020-2022 Andy Maleh. See [LICENSE.txt](LICENSE.txt) for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.1
@@ -2,17 +2,17 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: array_include_methods 1.4.0 ruby lib
5
+ # stub: array_include_methods 1.5.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "array_include_methods".freeze
9
- s.version = "1.4.0"
9
+ s.version = "1.5.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Andy Maleh".freeze]
14
- s.date = "2021-09-26"
15
- s.description = "Array#include_all? & Array#include_any? methods missing from basic Ruby Array API".freeze
14
+ s.date = "2023-02-17"
15
+ s.description = "Array#include_all?, Array#include_any?, Array#include_array?, Array#array_index, Array#counts, and Array#duplicates methods missing from basic Ruby Array API. Compatible with Ruby, JRuby, Opal, and RubyMotion.".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "CHANGELOG.md",
@@ -25,12 +25,13 @@ Gem::Specification.new do |s|
25
25
  "README.md",
26
26
  "VERSION",
27
27
  "array_include_methods.gemspec",
28
- "lib/array_include_methods.rb"
28
+ "lib/array_include_methods.rb",
29
+ "lib/array_include_methods/array.rb"
29
30
  ]
30
31
  s.homepage = "http://github.com/AndyObtiva/array_include_methods".freeze
31
32
  s.licenses = ["MIT".freeze]
32
- s.rubygems_version = "3.2.22".freeze
33
- s.summary = "Array#include_all? & Array#include_any? methods missing from basic Ruby Array API".freeze
33
+ s.rubygems_version = "3.3.3".freeze
34
+ s.summary = "Array#include_all?, Array#include_any?, and other methods missing from basic Ruby Array API".freeze
34
35
 
35
36
  if s.respond_to? :specification_version then
36
37
  s.specification_version = 4
@@ -0,0 +1,138 @@
1
+ if ['opal', 'rubymotion'].include?(RUBY_ENGINE)
2
+ # Create a shim using method that does nothing since we monkey-patch in Opal earlier in `refine` method
3
+ def self.using(refinement)
4
+ # NO OP
5
+ end
6
+
7
+ module ArrayIncludeMethods
8
+ def self.refine(class_or_module, &refinement)
9
+ class_or_module.class_eval(&refinement)
10
+ end
11
+ end
12
+ end
13
+
14
+ module ArrayIncludeMethods
15
+ refine Array do
16
+ # Returns `true` if all of the given `array` elements are present in `self`,
17
+ # otherwise returns `false`
18
+ # Always returns `true` if the given `array` is empty
19
+ # `same_sort` kwarg indicates that array must have the same sort as `self`. By default, it is `false`
20
+ # e.g. [1,2,3].include_all?(2,3, same_sort: true) => true
21
+ def include_all?(*array)
22
+ options = array.last.is_a?(Hash) && array.last.has_key?(:same_sort) ? array.pop : {same_sort: false}
23
+ same_sort = options[:same_sort]
24
+ return false if array.size > self.size
25
+ self_copy = self.dup
26
+ array_copy = array.dup
27
+ book_keeping_array_copy = array.dup
28
+ self_element_index = last_element_index = -1
29
+ array_copy.each do |element|
30
+ if self_copy.include?(element)
31
+ last_element_index = self_element_index
32
+ self_element_index = self_copy.index(element)
33
+ return false if same_sort && self_element_index < last_element_index
34
+ self_copy.delete_at(self_element_index)
35
+ book_keeping_array_copy.delete(element)
36
+ else
37
+ return false
38
+ end
39
+ end
40
+ book_keeping_array_copy.empty?
41
+ end
42
+
43
+ # Returns `true` if the given `array` is present in `self` (in the same element order without repetition)
44
+ # Always returns `true` if the given `array` is empty
45
+ # Always returns `false` if the given `array` is nil
46
+ def include_array?(array)
47
+ return false if array.nil?
48
+ if array.size > self.size
49
+ false
50
+ else
51
+ size_diff = self.size - array.size
52
+ (size_diff + 1).times.any? do |start_index|
53
+ self[start_index, array.size] == array
54
+ end
55
+ end
56
+ end
57
+
58
+ # Returns `true` if any of the given `array` elements are present in `self`,
59
+ # otherwise returns `false`
60
+ # Always returns `true` if the given `array` is empty
61
+ def include_any?(*array)
62
+ !array.nil? && (array.empty? || !(self & array).empty?)
63
+ end
64
+
65
+ def array_index(array)
66
+ result_array_index = -1
67
+ return result_array_index if array.nil?
68
+ if array.size <= self.size
69
+ size_diff = self.size - array.size
70
+ current_array_index = nil
71
+ result = (size_diff + 1).times.any? do |start_index|
72
+ current_array_index = start_index
73
+ self[start_index, array.size] == array
74
+ end
75
+ result_array_index = current_array_index if result
76
+ end
77
+ result_array_index
78
+ end
79
+
80
+ def array_intersection_indexes(array)
81
+ array_intersection_and_diff_indexes(array)[:intersection_indexes]
82
+ end
83
+ alias array_intersection_indices array_intersection_indexes
84
+
85
+ def array_intersection(array)
86
+ array_intersection_indexes(array).map { |index| self[index] }
87
+ end
88
+
89
+ def array_diff_indexes(array)
90
+ array_intersection_and_diff_indexes(array)[:diff_indexes]
91
+ end
92
+ alias array_diff_indices array_diff_indexes
93
+ alias array_difference_indexes array_diff_indexes
94
+ alias array_difference_indices array_diff_indexes
95
+
96
+ def array_diff(array)
97
+ array_diff_indexes(array).map { |index| self[index] }
98
+ end
99
+ alias array_difference array_diff
100
+
101
+ # Returns a hash of counts of every element in the array,
102
+ # performed in linear time (running time of O(n))
103
+ def counts
104
+ inject({}) do |count_hash, element|
105
+ count_hash[element] ||= 0
106
+ count_hash[element] += 1
107
+ count_hash
108
+ end
109
+ end
110
+
111
+ # Returns a single occurrence of all elements that repeated in an array,
112
+ # performed in linear time (running time of O(n)).
113
+ def duplicates
114
+ counts.select { |element, count| count > 1 }.keys
115
+ end
116
+
117
+ private
118
+
119
+ def array_intersection_and_diff_indexes(array)
120
+ return {intersection_indexes: [], diff_indexes: self.size.times.to_a} if array.nil?
121
+ intersection_indexes = []
122
+ diff_indexes = []
123
+ array_current_index = 0
124
+ each_with_index do |element, index|
125
+ if element == array[array_current_index]
126
+ intersection_indexes << index
127
+ array_current_index += 1
128
+ else
129
+ diff_indexes << index
130
+ end
131
+ end
132
+ {
133
+ intersection_indexes: intersection_indexes,
134
+ diff_indexes: diff_indexes
135
+ }
136
+ end
137
+ end
138
+ end
@@ -1,106 +1,7 @@
1
- module ArrayIncludeMethods
2
- if RUBY_PLATFORM == 'opal'
3
- def self.refine(class_or_module, &refinement)
4
- class_or_module.class_eval(&refinement)
5
- end
6
- end
7
- refine Array do
8
- # Returns `true` if all of the given `array` elements are present in `self`,
9
- # otherwise returns `false`
10
- # Always returns `true` if the given `array` is empty
11
- # `same_sort` option indicates that array must have the same sort as `self`. By default, it is `false`
12
- def include_all?(*array, same_sort: false)
13
- return false if array.size > self.size
14
- self_copy = self.dup
15
- array_copy = array.dup
16
- book_keeping_array_copy = array.dup
17
- self_element_index = last_element_index = -1
18
- array_copy.each do |element|
19
- if self_copy.include?(element)
20
- last_element_index = self_element_index
21
- self_element_index = self_copy.index(element)
22
- return false if same_sort && self_element_index < last_element_index
23
- self_copy.delete_at(self_element_index)
24
- book_keeping_array_copy.delete(element)
25
- else
26
- return false
27
- end
28
- end
29
- book_keeping_array_copy.empty?
30
- end
31
-
32
- # Returns `true` if the given `array` is present in `self` (in the same element order without repetition)
33
- # Always returns `true` if the given `array` is empty
34
- # Always returns `false` if the given `array` is nil
35
- def include_array?(array)
36
- return false if array.nil?
37
- if array.size > self.size
38
- false
39
- else
40
- size_diff = self.size - array.size
41
- (size_diff + 1).times.any? do |start_index|
42
- self[start_index, array.size] == array
43
- end
44
- end
45
- end
46
-
47
- # Returns `true` if any of the given `array` elements are present in `self`,
48
- # otherwise returns `false`
49
- # Always returns `true` if the given `array` is empty
50
- def include_any?(*array)
51
- !array.nil? && (array.empty? || !(self & array).empty?)
52
- end
53
-
54
- def array_index(array)
55
- result_array_index = -1
56
- return result_array_index if array.nil?
57
- if array.size <= self.size
58
- size_diff = self.size - array.size
59
- current_array_index = nil
60
- result = (size_diff + 1).times.any? do |start_index|
61
- current_array_index = start_index
62
- self[start_index, array.size] == array
63
- end
64
- result_array_index = current_array_index if result
65
- end
66
- result_array_index
67
- end
68
-
69
- def array_intersection_indexes(array)
70
- array_intersection_and_diff_indexes(array)[:intersection_indexes]
71
- end
72
- alias array_intersection_indices array_intersection_indexes
73
-
74
- def array_diff_indexes(array)
75
- array_intersection_and_diff_indexes(array)[:diff_indexes]
76
- end
77
- alias array_diff_indices array_diff_indexes
78
-
79
- private
80
-
81
- def array_intersection_and_diff_indexes(array)
82
- return {intersection_indexes: [], diff_indexes: self.size.times.to_a} if array.nil?
83
- intersection_indexes = []
84
- diff_indexes = []
85
- array_current_index = 0
86
- each_with_index do |element, index|
87
- if element == array[array_current_index]
88
- intersection_indexes << index
89
- array_current_index += 1
90
- else
91
- diff_indexes << index
92
- end
93
- end
94
- {
95
- intersection_indexes: intersection_indexes,
96
- diff_indexes: diff_indexes
97
- }
98
- end
99
- end
100
- end
101
- if RUBY_PLATFORM == 'opal'
102
- # Create a shim using method that does nothing since we monkey-patch in Opal earlier in `refine` method
103
- def self.using(refinement)
104
- # NO OP
1
+ begin
2
+ Motion::Project::App.setup do |app|
3
+ app.files += [File.join(__dir__, 'array_include_methods', 'array.rb')]
105
4
  end
5
+ rescue
6
+ require_relative 'array_include_methods/array'
106
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: array_include_methods
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-26 00:00:00.000000000 Z
11
+ date: 2023-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -122,8 +122,9 @@ dependencies:
122
122
  - - ">"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
- description: Array#include_all? & Array#include_any? methods missing from basic Ruby
126
- Array API
125
+ description: Array#include_all?, Array#include_any?, Array#include_array?, Array#array_index,
126
+ Array#counts, and Array#duplicates methods missing from basic Ruby Array API. Compatible
127
+ with Ruby, JRuby, Opal, and RubyMotion.
127
128
  email: andy.am@gmail.com
128
129
  executables: []
129
130
  extensions: []
@@ -138,6 +139,7 @@ files:
138
139
  - VERSION
139
140
  - array_include_methods.gemspec
140
141
  - lib/array_include_methods.rb
142
+ - lib/array_include_methods/array.rb
141
143
  homepage: http://github.com/AndyObtiva/array_include_methods
142
144
  licenses:
143
145
  - MIT
@@ -157,9 +159,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
159
  - !ruby/object:Gem::Version
158
160
  version: '0'
159
161
  requirements: []
160
- rubygems_version: 3.2.22
162
+ rubygems_version: 3.3.3
161
163
  signing_key:
162
164
  specification_version: 4
163
- summary: Array#include_all? & Array#include_any? methods missing from basic Ruby Array
164
- API
165
+ summary: Array#include_all?, Array#include_any?, and other methods missing from basic
166
+ Ruby Array API
165
167
  test_files: []