everythingrb 0.2.1 → 0.2.2

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: 81c7beca1a15139ecb5a59977740b65244d05f16b157ca45fb0d2995c7503bd3
4
- data.tar.gz: d6b6fffa5d7be4890ac617b17c785e289e6e6f3385fa941a72f211f47e2a7c0c
3
+ metadata.gz: 637e088cea35038c9cea8b54e127e795ddb06c1d7c0011e55accd5930cf2217d
4
+ data.tar.gz: '059758659229885856daaa52dfcfd33e6b4bdad6e29923e71e3dd887f7de390d'
5
5
  SHA512:
6
- metadata.gz: b3089b90018085b856d7fd34a133ec9174753a371d7c6d56088c82fbbd5c46a1e5c4c3a2c0d9e967b1eaf28d84dd322b5b8a919a93bd5f71157e2638bdfaabfd
7
- data.tar.gz: 5f5e058681ad88168d0a37c7580fd29483f755a895d0fce088e8db9904136d7a118d6b7557375fc7675f8b157da16b61274eeaf0378a53e53863632723dcccc0
6
+ metadata.gz: 97b3766b8382f7e160e5996ce03497368770450cc76d91acfa094c80dc9812ae1d27ed66d95988e9918bdd3b6887b84bcc52ed4df70aacac5453872bab0104ca
7
+ data.tar.gz: f4991d65bf9ef6a3398e0808fa4d794816e4e53874ee712a66f18728ff6cd495d7f2f1f2a86ee40af5a3e5a435b78ff10defca50ea120bd423af30cf5953a90e
data/CHANGELOG.md CHANGED
@@ -23,6 +23,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
23
 
24
24
  ### Removed
25
25
 
26
+ ## [0.2.2] - 12025-03-03
27
+
28
+ ### Added
29
+
30
+ - Added `Array#key_map` and `Array#dig_map` for mapping over `Hash`
31
+ - Added `with_index:` keyword argument to `Array#join_map`. Defaults to `false`
32
+ - Added `Enumerable#join_map`
33
+ - Added `Array#deep_freeze` and `Hash#deep_freeze` to recursively freeze the underlying values
34
+
26
35
  ## [0.2.1] - 12025-03-01
27
36
 
28
37
  ### Added
@@ -88,7 +97,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
97
 
89
98
  - Added alias `each` to `each_pair` in OpenStruct for better enumerable compatibility
90
99
 
91
- [unreleased]: https://github.com/itsthedevman/everythingrb/compare/v0.2.1...HEAD
100
+ [unreleased]: https://github.com/itsthedevman/everythingrb/compare/v0.2.2...HEAD
101
+ [0.2.2]: https://github.com/itsthedevman/everythingrb/compare/v0.2.1...v0.2.2
92
102
  [0.2.1]: https://github.com/itsthedevman/everythingrb/compare/v0.2.0...v0.2.1
93
103
  [0.2.0]: https://github.com/itsthedevman/everythingrb/compare/v0.1.2...v0.2.0
94
104
  [0.1.2]: https://github.com/itsthedevman/everythingrb/compare/v0.1.1...v0.1.2
data/README.md CHANGED
@@ -19,24 +19,29 @@ I'm currently looking for opportunities where I can tackle meaningful problems a
19
19
  - [Core Extensions](#core-extensions)
20
20
  - [Array](#array)
21
21
  - [join_map](#join_map)
22
+ - [key_map](#key_map)
23
+ - [dig_map](#dig_map)
24
+ - [Enumerable](#enumerable)
25
+ - [join_map](#join_map-1)
22
26
  - [Hash](#hash)
23
27
  - [to_struct](#to_struct)
24
28
  - [to_ostruct](#to_ostruct)
25
29
  - [to_istruct](#to_istruct)
26
- - [join_map](#join_map-1)
30
+ - [join_map](#join_map-2)
27
31
  - [Module](#module)
28
32
  - [attr_predicate](#attr_predicate)
29
33
  - [OpenStruct](#openstruct)
30
34
  - [each](#each)
31
35
  - [map](#map)
32
36
  - [filter_map](#filter_map)
33
- - [join_map](#join_map-2)
37
+ - [join_map](#join_map-3)
34
38
  - [String](#string)
35
39
  - [to_h / to_a](#to_h--to_a)
36
40
  - [to_istruct](#to_istruct-1)
37
41
  - [to_ostruct](#to_ostruct-1)
38
42
  - [to_struct](#to_struct-1)
39
43
  - [to_deep_h](#to_deep_h)
44
+ - [with_quotes / in_quotes](#with_quotes--in_quotes)
40
45
  - [Requirements](#requirements)
41
46
  - [Contributing](#contributing)
42
47
  - [License](#license)
@@ -76,11 +81,74 @@ $ gem install everythingrb
76
81
  ### Array
77
82
 
78
83
  #### `join_map`
79
- Combines `filter_map` and `join` operations in one convenient method.
84
+ Combines `filter_map` and `join` operations in one convenient method. Optionally provides the index to the block.
80
85
 
81
86
  ```ruby
87
+ # Without index
82
88
  [1, 2, nil, 3].join_map(" ") { |n| n&.to_s if n&.odd? }
83
89
  # => "1 3"
90
+
91
+ # With index
92
+ ["a", "b", "c"].join_map(", ", with_index: true) { |char, i| "#{i}:#{char}" }
93
+ # => "0:a, 1:b, 2:c"
94
+
95
+ # Default behavior without block
96
+ [1, 2, nil, 3].join_map(", ")
97
+ # => "1, 2, 3"
98
+ ```
99
+
100
+ #### `key_map`
101
+ Extracts a specific key from each hash in an array.
102
+
103
+ ```ruby
104
+ users = [
105
+ { name: "Alice", age: 30 },
106
+ { name: "Bob", age: 25 }
107
+ ]
108
+
109
+ users.key_map(:name)
110
+ # => ["Alice", "Bob"]
111
+ ```
112
+
113
+ #### `dig_map`
114
+ Extracts nested values from each hash in an array using the `dig` method.
115
+
116
+ ```ruby
117
+ data = [
118
+ { user: { profile: { name: "Alice" } } },
119
+ { user: { profile: { name: "Bob" } } }
120
+ ]
121
+
122
+ data.dig_map(:user, :profile, :name)
123
+ # => ["Alice", "Bob"]
124
+ ```
125
+
126
+ #### `deep_freeze`
127
+ Recursively freezes an array and all of its nested elements.
128
+
129
+ ```ruby
130
+ array = ["hello", { name: "Alice" }, [1, 2, 3]]
131
+ array.deep_freeze
132
+ # => All elements and nested structures are now frozen
133
+ ```
134
+
135
+ ### Enumerable
136
+
137
+ #### `join_map`
138
+ Combines filtering, mapping and joining operations into one convenient method.
139
+
140
+ ```ruby
141
+ # Basic usage with arrays
142
+ [1, 2, nil, 3].join_map(", ") { |n| n&.to_s if n&.odd? }
143
+ # => "1, 3"
144
+
145
+ # Works with any Enumerable
146
+ (1..10).join_map(" | ") { |n| "num#{n}" if n.even? }
147
+ # => "num2 | num4 | num6 | num8 | num10"
148
+
149
+ # Supports with_index option
150
+ %w[a b c].join_map("-", with_index: true) { |char, i| "#{i}:#{char}" }
151
+ # => "0:a-1:b-2:c"
84
152
  ```
85
153
 
86
154
  ### Hash
@@ -124,6 +192,15 @@ Similar to Array#join_map but operates on hash values.
124
192
  # => "a 1 b 2 d 3"
125
193
  ```
126
194
 
195
+ #### `deep_freeze`
196
+ Recursively freezes a hash and all of its nested values.
197
+
198
+ ```ruby
199
+ hash = { user: { name: "Alice", roles: ["admin", "user"] } }
200
+ hash.deep_freeze
201
+ # => Hash and all nested structures are now frozen
202
+ ```
203
+
127
204
  ### Module
128
205
 
129
206
  #### `attr_predicate`
@@ -5,22 +5,80 @@ class Array
5
5
  # Combines filter_map and join operations
6
6
  #
7
7
  # @param join_with [String] The delimiter to join elements with (defaults to empty string)
8
+ # @param with_index [Boolean] Whether to include the index in the block (defaults to false)
8
9
  #
9
- # @yield [Object] Block that filters and transforms array elements
10
+ # @yield [element, index] Block that filters and transforms array elements
11
+ # @yieldparam element [Object] The current element
12
+ # @yieldparam index [Integer] The index of the current element (only if with_index: true)
10
13
  #
11
14
  # @return [String] Joined string of filtered and transformed elements
12
15
  #
13
- # @example
16
+ # @example Without index
14
17
  # [1, 2, nil, 3].join_map(" ") { |n| n&.to_s if n&.odd? }
15
18
  # # => "1 3"
16
19
  #
17
- # @example
20
+ # @example With index
21
+ # ["a", "b", "c"].join_map(", ", with_index: true) { |char, i| "#{i}:#{char}" }
22
+ # # => "0:a, 1:b, 2:c"
23
+ #
24
+ # @example Default behavior without block
18
25
  # [1, 2, nil, 3].join_map(", ")
19
26
  # # => "1, 2, 3"
20
27
  #
21
- def join_map(join_with = "", &block)
28
+ def join_map(join_with = "", with_index: false, &block)
22
29
  block = ->(i) { i } if block.nil?
23
30
 
24
- filter_map(&block).join(join_with)
31
+ if with_index
32
+ filter_map.with_index(&block).join(join_with)
33
+ else
34
+ filter_map(&block).join(join_with)
35
+ end
36
+ end
37
+
38
+ #
39
+ # Maps over hash keys to extract values for a specific key
40
+ #
41
+ # @param key [Symbol, String] The key to extract
42
+ #
43
+ # @return [Array] Array of values
44
+ #
45
+ # @example
46
+ # [{name: 'Alice', age: 30}, {name: 'Bob', age: 25}].key_map(:name)
47
+ # # => ['Alice', 'Bob']
48
+ #
49
+ def key_map(key)
50
+ map { |v| v[key] }
51
+ end
52
+
53
+ #
54
+ # Maps over hash keys to extract nested values using dig
55
+ #
56
+ # @param keys [Array<Symbol, String>] The keys to dig through
57
+ #
58
+ # @return [Array] Array of nested values
59
+ #
60
+ # @example
61
+ # [
62
+ # {user: {profile: {name: 'Alice'}}},
63
+ # {user: {profile: {name: 'Bob'}}}
64
+ # ].dig_map(:user, :profile, :name)
65
+ # # => ['Alice', 'Bob']
66
+ #
67
+ def dig_map(*keys)
68
+ map { |v| v.dig(*keys) }
69
+ end
70
+
71
+ #
72
+ # Recursively freezes self and all of its contents
73
+ #
74
+ # @return [self] Returns the frozen array
75
+ #
76
+ # @example Freeze an array with nested structures
77
+ # ["hello", { name: "Alice" }, [1, 2, 3]].deep_freeze
78
+ # # => All elements and nested structures are now frozen
79
+ #
80
+ def deep_freeze
81
+ each { |v| v.respond_to?(:deep_freeze) ? v.deep_freeze : v.freeze }
82
+ freeze
25
83
  end
26
84
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerable
4
+ #
5
+ # Combines filter_map and join operations
6
+ #
7
+ # @param join_with [String] The delimiter to join elements with (defaults to empty string)
8
+ # @param with_index [Boolean] Whether to include the index in the block (defaults to false)
9
+ #
10
+ # @yield [element, index] Block that filters and transforms array elements
11
+ # @yieldparam element [Object] The current element
12
+ # @yieldparam index [Integer] The index of the current element (only if with_index: true)
13
+ #
14
+ # @return [String] Joined string of filtered and transformed elements
15
+ #
16
+ # @example Without index
17
+ # [1, 2, nil, 3].join_map(" ") { |n| n&.to_s if n&.odd? }
18
+ # # => "1 3"
19
+ #
20
+ # @example With index
21
+ # ["a", "b", "c"].join_map(", ", with_index: true) { |char, i| "#{i}:#{char}" }
22
+ # # => "0:a, 1:b, 2:c"
23
+ #
24
+ # @example Default behavior without block
25
+ # [1, 2, nil, 3].join_map(", ")
26
+ # # => "1, 2, 3"
27
+ #
28
+ def join_map(join_with = "", with_index: false, &block)
29
+ block = ->(i) { i } if block.nil?
30
+
31
+ if with_index
32
+ filter_map.with_index(&block).join(join_with)
33
+ else
34
+ filter_map(&block).join(join_with)
35
+ end
36
+ end
37
+ end
@@ -85,4 +85,18 @@ class Hash
85
85
 
86
86
  OpenStruct.new(**transform_values { |value| recurse.call(value) })
87
87
  end
88
+
89
+ #
90
+ # Recursively freezes self and all of its values
91
+ #
92
+ # @return [self] Returns the frozen hash
93
+ #
94
+ # @example Freeze a hash with nested structures
95
+ # { user: { name: "Alice", roles: ["admin"] } }.deep_freeze
96
+ # # => Hash and all nested structures are now frozen
97
+ #
98
+ def deep_freeze
99
+ each_value { |v| v.respond_to?(:deep_freeze) ? v.deep_freeze : v.freeze }
100
+ freeze
101
+ end
88
102
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Everythingrb
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
5
5
  end
data/lib/everythingrb.rb CHANGED
@@ -5,6 +5,7 @@ require "json"
5
5
 
6
6
  require_relative "everythingrb/version"
7
7
  require_relative "everythingrb/core/array"
8
+ require_relative "everythingrb/core/enumerable"
8
9
  require_relative "everythingrb/core/hash"
9
10
  require_relative "everythingrb/core/module"
10
11
  require_relative "everythingrb/core/ostruct"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: everythingrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-01 00:00:00.000000000 Z
11
+ date: 2025-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ostruct
@@ -58,6 +58,7 @@ files:
58
58
  - flake.nix
59
59
  - lib/everythingrb.rb
60
60
  - lib/everythingrb/core/array.rb
61
+ - lib/everythingrb/core/enumerable.rb
61
62
  - lib/everythingrb/core/hash.rb
62
63
  - lib/everythingrb/core/module.rb
63
64
  - lib/everythingrb/core/ostruct.rb