Skip to content

Commit 78ce831

Browse files
committed
add FILTER function
Pretty much a copy-paste of the existing MAP function.
1 parent d77dd3b commit 78ce831

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ Selections: `CASE` (syntax see [spec](https://github.com/rubysolo/dentaku/blob/m
152152

153153
String: `LEFT`, `RIGHT`, `MID`, `LEN`, `FIND`, `SUBSTITUTE`, `CONCAT`, `CONTAINS`
154154

155+
Collection: `MAP`, `FILTER`, `ALL`, `ANY`
156+
155157
RESOLVING DEPENDENCIES
156158
----------------------
157159

lib/dentaku/ast/functions/filter.rb

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
require_relative '../function'
2+
require_relative '../../exceptions'
3+
4+
module Dentaku
5+
module AST
6+
class Filter < Function
7+
def self.min_param_count
8+
3
9+
end
10+
11+
def self.max_param_count
12+
3
13+
end
14+
15+
def deferred_args
16+
[1, 2]
17+
end
18+
19+
def value(context = {})
20+
collection = @args[0].value(context)
21+
item_identifier = @args[1].identifier
22+
expression = @args[2]
23+
24+
Array(collection).filter do |item_value|
25+
expression.value(
26+
context.merge(
27+
FlatHash.from_hash_with_intermediates(item_identifier => item_value)
28+
)
29+
)
30+
end
31+
end
32+
end
33+
end
34+
end
35+
36+
Dentaku::AST::Function.register_class(:filter, Dentaku::AST::Filter)

spec/ast/filter_spec.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require 'spec_helper'
2+
require 'dentaku/ast/functions/filter'
3+
require 'dentaku'
4+
5+
describe Dentaku::AST::Filter do
6+
it 'excludes unmatched values' do
7+
result = Dentaku('SUM(FILTER(vals, val, val > 1))', vals: [1, 2, 3])
8+
expect(result).to eq(5)
9+
end
10+
11+
it 'works with a single value if needed for some reason' do
12+
result = Dentaku('FILTER(vals, val, val > 1)', vals: 1)
13+
expect(result).to eq([])
14+
15+
result = Dentaku('FILTER(vals, val, val > 1)', vals: 2)
16+
expect(result).to eq([2])
17+
end
18+
end

0 commit comments

Comments
 (0)