You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
12
-`match ... end` pattern matching syntax with value matching, type matching, `_` wildcard, maybe destructuring (`just v`/`none`), list destructuring (`[a b ...rest]`), and dict destructuring (`{ 'key': v }`)
13
13
-`map` on dictionaries (maps over values, preserving keys)
14
14
- Functions
15
+
-`filter` builtin now supports dictionaries, filtering by value while preserving keys
Copy file name to clipboardExpand all lines: doc/functions.inc.html
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -237,7 +237,7 @@ <h1 id="functions-lists">Lists <a class="section-link" href="#functions-lists" a
237
237
<tr><td><code>nth</code></td><td>Return the nth element (0-based).</td><td><code>([a] <spanclass="sig-type sig-type-int">int</span> -- a)</code></td></tr>
238
238
<tr><td><code>reverse</code></td><td>Reverse a list.</td><td><code>(<spanclass="sig-type sig-type-list">list</span> -- <spanclass="sig-type sig-type-list">list</span>)</code></td></tr>
239
239
<tr><td><code>sum</code></td><td>Sum numeric values in a list.</td><td><code>([<spanclass="sig-type sig-type-numeric">numeric</span>] -- <spanclass="sig-type sig-type-numeric">numeric</span>)</code></td></tr>
240
-
<tr><td><code>filter</code></td><td>Filter a list by a predicate quotation.</td><td><code>([a] (a -- <spanclass="sig-type sig-type-bool">bool</span>) -- [a])</code></td></tr>
240
+
<tr><td><code>filter</code></td><td>Filter a list or dictionary by a predicate quotation, returning a new list or dictionary. The input collection is not modified in place. For dictionaries, the quotation is applied to each value and matching entries are preserved.</td><td><code>([a] (a -- <spanclass="sig-type sig-type-bool">bool</span>) -- [a])</code>, <code>(<spanclass="sig-type sig-type-dict">dict</span> (a -- <spanclass="sig-type sig-type-bool">bool</span>) -- <spanclass="sig-type sig-type-dict">dict</span>)</code></td></tr>
241
241
<tr><td><code>linearSearch</code></td><td>Return the first element that satisfies a predicate quotation, or <code>none</code> when missing.</td><td><code>([a] (a -- <spanclass="sig-type sig-type-bool">bool</span>) -- <spanclass="sig-type sig-type-maybe">Maybe</span>[a])</code></td></tr>
242
242
<tr><td><code>any</code></td><td>Return true if any element satisfies the predicate.</td><td><code>([a] (a -- <spanclass="sig-type sig-type-bool">bool</span>) -- <spanclass="sig-type sig-type-bool">bool</span>)</code></td></tr>
243
243
<tr><td><code>all</code></td><td>Return true if all elements satisfy the predicate.</td><td><code>([a] (a -- <spanclass="sig-type sig-type-bool">bool</span>) -- <spanclass="sig-type sig-type-bool">bool</span>)</code></td></tr>
Copy file name to clipboardExpand all lines: doc/mshell.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -741,7 +741,7 @@ end
741
741
-`nth`: Nth element of list (0-based) `([a] int -- a)`
742
742
-`reverse`: Reverse list, `(list -- list)`
743
743
-`sum`: Sum of list, `([numeric] -- numeric)`
744
-
-`filter`: Filter list, `([a] (a -- bool) -- [a])`
744
+
-`filter`: Filter a list or dictionary, returning a new collection. The input list or dictionary is not modified in place. For dictionaries, the quotation is applied to each value and matching entries are preserved. `([a] (a -- bool) -- [a])`, `(dict (a -- bool) -- dict)`
745
745
-`any`: Check if any element in list satisfies a condition, `([a] (a -- bool) -- bool)`
746
746
-`all`: Check if all elements in list satisfy a condition, `([a] (a -- bool) -- bool)`
747
747
-`skip`: Skip first n elements of list, `(list int -- list)`
@@ -779,6 +779,7 @@ end
779
779
-`values`: Get values from dictionary. Sorted. `(dict -- [str])`
780
780
-`keyValues`: Get key/value pairs from dictionary as a list of lists. Each inner list is a two-element list with the key and value. Sorted by key. `(dict -- [[str a]])`
781
781
-`map`: Map a quotation over dictionary values. Keys are preserved. `(dict (a -- b) -- dict)`
782
+
-`filter`: Filter dictionary values with a predicate quotation, returning a new dictionary. Keys are preserved for matching entries, and the original dictionary is not modified in place. `(dict (a -- bool) -- dict)`
782
783
-`in`: Check if key exists in dictionary. `(dict str -- bool)`
Copy file name to clipboardExpand all lines: mshell/Evaluator.go
+77Lines changed: 77 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -4651,6 +4651,83 @@ MainLoop:
4651
4651
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'just' operation on an empty stack.\n", t.Line, t.Column))
4652
4652
}
4653
4653
stack.Push(&Maybe{obj: o})
4654
+
} elseift.Lexeme=="filter" {
4655
+
obj1, obj2, err:=stack.Pop2(t)
4656
+
iferr!=nil {
4657
+
returnstate.FailWithMessage(err.Error())
4658
+
}
4659
+
4660
+
fn, ok:=obj1.(*MShellQuotation)
4661
+
if!ok {
4662
+
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: The first parameter in 'filter' is expected to be a function, found a %s (%s)\n", t.Line, t.Column, obj1.TypeName(), obj1.DebugString()))
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: The function in 'filter' did not return a single value, found %d values.\n", t.Line, t.Column, len(filterStack)))
4684
+
}
4685
+
4686
+
filterResult, _:=filterStack.Pop()
4687
+
filterBool, ok:=filterResult.(MShellBool)
4688
+
if!ok {
4689
+
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: The function in 'filter' did not return a bool, found a %s (%s).\n", t.Line, t.Column, filterResult.TypeName(), filterResult.DebugString()))
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: The function in 'filter' did not return a single value, found %d values.\n", t.Line, t.Column, len(filterStack)))
4715
+
}
4716
+
4717
+
filterResult, _:=filterStack.Pop()
4718
+
filterBool, ok:=filterResult.(MShellBool)
4719
+
if!ok {
4720
+
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: The function in 'filter' did not return a bool, found a %s (%s).\n", t.Line, t.Column, filterResult.TypeName(), filterResult.DebugString()))
4721
+
}
4722
+
4723
+
iffilterBool.Value {
4724
+
newDict.Items[key] =value
4725
+
}
4726
+
}
4727
+
stack.Push(newDict)
4728
+
default:
4729
+
returnstate.FailWithMessage(fmt.Sprintf("%d:%d: The second parameter in 'filter' is expected to be a list or dictionary, found a %s (%s)\n", t.Line, t.Column, obj2.TypeName(), obj2.DebugString()))
0 commit comments