Class: Janeway::Interpreters::ArraySliceSelectorDeleteIf

Inherits:
ArraySliceSelectorInterpreter show all
Includes:
IterationHelper
Defined in:
lib/janeway/interpreters/array_slice_selector_delete_if.rb

Overview

Delete values that match the array slice selector and yield true from the block

Constant Summary

Constants inherited from Base

Base::NOTHING

Instance Attribute Summary

Attributes inherited from Base

#next, #node

Instance Method Summary collapse

Methods included from IterationHelper

#make_yield_proc, #normalized_path

Methods inherited from ArraySliceSelectorInterpreter

#as_json

Methods inherited from Base

#as_json, #selector, #to_s, #type

Constructor Details

#initialize(node, &block) ⇒ ArraySliceSelectorDeleteIf

Returns a new instance of ArraySliceSelectorDeleteIf.

Parameters:



13
14
15
16
17
18
19
# File 'lib/janeway/interpreters/array_slice_selector_delete_if.rb', line 13

def initialize(node, &block)
  super(node)
  @block = block

  # Make a proc that yields the correct number of values to a block
  @yield_proc = make_yield_proc(&block)
end

Instance Method Details

#interpret(input, _parent, _root, path) ⇒ Array

Delete values at the indices matched by the array slice selector

Parameters:

  • input (Array, Hash)

    the results of processing so far

  • _parent (Array, Hash)

    parent of the input object

  • _root (Array, Hash)

    the entire input

  • path (Array<String>)

    elements of normalized path to the current input

Returns:

  • (Array)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/janeway/interpreters/array_slice_selector_delete_if.rb', line 28

def interpret(input, _parent, _root, path)
  return [] unless input.is_a?(Array)
  return [] if selector&.step&.zero? # RFC: When step is 0, no elements are selected.

  # Calculate the upper and lower indices of the target range
  lower = selector.lower_index(input.size)
  upper = selector.upper_index(input.size)

  # Convert bounds and step to index values.
  # Omit the final index, since no value is collected for that.
  # Delete indexes from largest to smallest, so that deleting an index does
  # not change the remaining indexes
  results = []
  if selector.step.positive?
    indexes = lower.step(to: upper - 1, by: selector.step).to_a
    indexes.reverse_each do |i|
      next unless @yield_proc.call(input[i], input, path + [i])

      results << input.delete_at(i)
    end
    results.reverse
  else
    indexes = upper.step(to: lower + 1, by: selector.step).to_a
    indexes.each { |i| results << input.delete_at(i) }
    results
  end
end