Skip to main content

Array Comparison

Arrays are checked to ensure their contents also match the shape.

Simple Array Comparison
Kt.compare(value: [1], shape: [Integer]).match? # => true

Since arrays aren't usually a fixed length, we don't compare the length of the value and shape arrays.

Instead, we treat the contents of the shape array like any_of.

[String, Integer] is effectively shorthand for [Kt.any_of(String, Integer)].

Pseudo-Code of Array Comparison
array_matches = value.all? do |element|
shape.any? do |shape_element|
Kt.compare(value: element, shape: shape_element).match?
end
end

Seeing a few examples is probably the best way to understand how this works.

Sample Array Comparisons
Kt.compare(value: [1, 2, 3, 4, 5], shape: [Integer]).match? # => true
Kt.compare(value: ['a', 'b', 'c'], shape: [Integer]).match? # => false
Kt.compare(value: [1, 2, 'c'], shape: [Integer]).match? # => false
Kt.compare(value: ['a', 2, 'c', 4], shape: [Integer, String]).match? # => true

Fixed Length Arrays

We said arrays aren't usually a fixed length, but it does happen.

For this situation, the Ruby in operator is your friend.

Here's how you can check for an array of exactly 5 elements without a lot of typing.

Array length matching using the 'in' operator
value = [1, 2, 3, 4, 5]
shape = ->(v) { v in ([Integer] * 5) }
Kt.compare(value:, shape:).match? # => true

Specific Values at Specific Indexes

Ruby's in works well for when you want to check for specific values at specific indexes.

Array with specific values at specific indexes
value = [1, 'a', 2]
shape = ->(v) { v in [Integer, String, 2] }
Kt.compare(value:, shape:).match? # => true

Nested Arrays

Checks are recursive, so you can nest arrays as deep as you like.

Nested arrays
value = [1, [2, [3, 4]]]
shape = [Integer, [Integer, [Integer]]]
Kt.compare(value:, shape:).match? # => true