Library Name: (visualscheme data linq)
Language INtegrated Query (“LINQ”) is a popular feature of languages on the Common Language Runtime (“CLR”), intended to generalize querying of arbitrary collections with syntax familiar to SQL developers. On languages that do not feature Lisp’s homoiconic syntax, LINQ needs to be implemented by the compiler vendors, and developers must wait for bug fixes and new versions to extend LINQ functionality. But languages in the Lisp tradition, such as Scheme and IronScheme, were designed to allow developers to add their own novel syntax to the language itself.
The (visualscheme data linq) library wraps the (ironscheme linq) library and adds an additional (define-enumerable …) form to convert .NET IEnumerable instances into Scheme-compatible iterators.
Scheme iterators defined in (ironscheme linq) have nothing to do with LINQ as implemented in C# or VB.NET, except for behaving according to the C# specification for LINQ. It is 100% Scheme and not dependent at all on any specific CLR implementation of LINQ.
For this reason, we found it necessary to create an adapter from .NET to Scheme iterators defined in (ironscheme linq) that understands the core IEnumerable and IEnumerator interfaces, on which LINQ implementations in C# and VB.NET also rely. This is exactly what the (define-enumerable …) form does.
Signature | (define-enumerable <enumerable-name> <enumerable-instance-function> [as <typecast-type>]) |
Exported From | (visualscheme data linq) |
Type of Form | Syntax extension (macro) |
Description | (define-enumerable …) creates a standard Scheme iterator for a .NET collection that implements IEnumerable. IEnumerable implementations have a GetEnumerator() function that returns an IEnumerator instance suitable for that collection, allowing an iterator to be advanced, the current element in an iterator to be obtained, and for the entire iterator to be reset. |
Parameter | Description |
<enumerable-name> | The name given to the resulting form, representing a .NET iterator generator. |
<enumerable-instance-function> | The lambda or case-lambda expression used to create a fresh instance of the enumerable collection for which the iterator is being created. |
<typecast-type> | The specific type to cast the IEnumerable instance to, when necessary for correct iterator semantics. |
Examples
(define-enumerable reader/records ;; The simplest enumerable function is one that ;; merely returns an object implementing IEnumerable (lambda (reader) reader) as DbDataReader) |
(define-enumerable graph/triples (case-lambda [() (clr-prop-get Graph Triples (current-graph))]
[(graph) (begin (if (or (null? graph) (not (graph? graph))) (error "graph must be a non-null instance of Graph.") (if (not (eq? graph (current-graph))) (current-graph graph))) (clr-prop-get Graph Triples graph))]) as TreeIndexedTripleCollection) |
In the simplest case, the (define-enumerable …) macro takes a simple lambda form that returns the parameter it was passed, which must be a CLR type implementing IEnumerable. The GetEnumerator() function is invoked on it immediately to obtain the IEnumerator instance wrapped by the macro in a canonical Scheme iterator.
A more complicated example is when some global state, usually during development in a REPL, such as a tracked “current'' instance of something, obviates the need for passing the expression a specific enumerable instance; in this case a (case-lambda ..) expression can deal with invocation of the enumerable with zero parameters. In the second example above, the (visualscheme data rdf core) library provides a concept of the “current” graph, important to minimize typing REPL contexts, and so invoking the enumerable value without any parameters will essentially use (current-graph) as the enumerable instance in the second case clause. In other words, developers can provide a specific graph instance from which to obtain the enumerator, or, absent that, it will simply use the (current-graph) instance.
Like the .NET IEnumerator interface, which IEnumerable collections return via GetEnumerator(), Scheme iterators also are defined by three functions—a function to advance the iterator, a function to get the current item in the collection being iterated, and a function to reset the iterator. That made the implementation of the adapter somewhat simpler. This last function—reset—is a bit problematic, however, when dealing with .NET objects implementing the IEnumerator interface, because as a matter of experience they are notoriously non-regular, as what exactly “resetting” an iterator means was sadly left unspecified in the interface at the time Microsoft defined it.
One may occasionally encounter an IEnumerator instance that does what is expected, but only trial and error will reveal if the object “behaves.” The approach taken by (define-enumerable …) therefore is just to start all over with a fresh instance of the enumerable that generates the enumerator, when possible. Whether this is possible or not, depends once again how the implementer interpreted the interface requirements. Some do give you a fresh enumerator, and some return an already-existing one.
It is often helpful to specify a specific class type to cast the enumerator generated by the enumerable to, rather than rely on the generic IEnumerator interface to pick the “right” dispatch method, so this is an option using the optional “as <typecast-type>” clause.
The value returned by invocation of the enumerable form is ready now to be used in LINQ expressions.
(foreach t in (graph/triples (current-graph)) (display t) (newline)) |
LINQ expressions can be quite complex but essentially they allow you to filter and possibly combine multiple iterators to obtain or construct a meaningful subset (or superset) of data from all available data in the collection (or collections being combined). Note in the example above, we are calling the (current-graph) parameter and passing that into (graph/triples …), but we could have left it out, as the case-lambda expression used to define the enumerable would use (current-graph) by default, in the absence of a specific instance being passed into it.
The big advantage of using LINQ expressions is that they make explicit what might be hidden or implicit in “object oriented” wrappers of database entities. The famed “impedance mismatch” problem of object-relational mappers is bypassed altogether when using iterators with the declarative syntax of LINQ. While conversion to/from forms that are convenient for use in the programming language are inevitable, they need not be obscured by layers of object hierarchies that make what is going on less apparent, for the sake of creating the illusion that database entities are domain objects. They aren’t, so anything creating the illusion that they are is just overhead.
Signature | (iterator? <object>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Returns #t if the <object> passed in is an iterator; otherwise it returns #f. |
Parameter | Description |
<object> | A Scheme value that may or may not be an instance of an iterator. |
Examples
(iterator? (graph/triples)) => #t (iterator? '(1 2 3)) => #f |
Used as a guard to ensure that some passed-in object is an iterator before trying to use it in a LINQ expression.
Signature | (make-iterator <move-next-function> <get-current-function> <reset-function>) |
Exported From | (visualscheme data linq) |
Type of Form | Function (constructor of iterators) |
Description | Creates a new iterator suitable for use in LINQ expressions. |
Parameter | Description |
<move-next-function> | A function or lambda expression that performs the “move next” operation on the iterator. |
<get-current-function> | A function or lambda expression that performs the “get current” operation on the iterator. |
<reset-function> | A function or lambda expression that performs the “reset” operation on the iterator. |
Examples
The (define-enumerable …) macro uses (make-iterator …) to implement the adapter to .NET IEnumerable collections:
(define-syntax define-enumerable (lambda (x) (syntax-case x (as)
((_ enum-name enum-fn) #'(define-enumerable enum-name enum-fn as IEnumerable))
((_ enum-name enum-fn as enum-type) #'(define enum-name (case-lambda [() (let ((iter (enum-fn))) (make-iterator (lambda () (unless iter (set! iter (clr-call enum-type GetEnumerator (enum-fn)))) (clr-call IEnumerator MoveNext iter)) (lambda () (clr-prop-get IEnumerator Current iter)) (lambda () (set! iter (clr-call enum-type GetEnumerator (enum-fn))))))] [(obj) (let ((iter (enum-fn obj))) (make-iterator (lambda () (unless iter (set! iter (clr-call enum-type GetEnumerator (enum-fn obj)))) (clr-call IEnumerator MoveNext iter)) (lambda () (clr-prop-get IEnumerator Current iter)) (lambda () (set! iter (clr-call enum-type GetEnumerator (enum-fn obj))))))])))))) |
(make-iterator …) is a constructor created by the definition of the iterator record type in (ironscheme linq):
(define-record-type iterator (opaque #t) (fields move-next current reset)) |
Signature | (get-iterator <object>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | If the <object> passed has an iterator defined, then an iterator for that kind of object is returned. Supported iterator types are: grouping, lists, vectors, strings and hashtables. If the object passed in is already an iterator, it is simply returned. Otherwise, an assertion violation is raised. |
Parameter | Description |
<object> | A Scheme value that may or may not have an iterator defined for it. |
Examples
(get-iterator '(1 2 3)) ;; => #<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator> |
(get-iterator …) is unaware of types for which you may have created an iterator. To overcome this, you can do something like this:
(define my-get-iterator (lambda (obj) (cond [(clr-is DbDataReader obj) (reader/records obj)] [(clr-is Graph obj) (graph/all-triples obj)] [else (get-iterator obj)]))) |
Note that our example uses the iterator adapters returned from our (define-enumerable …) form but you can create your own iterators. The key point is, if there is an iterator for a type not otherwise specified by (get-iterator …) you simply need to wrap calling (get-iterator) in the else clause of your custom get-iterator implementation.
Signature | (trace-iterator <name> <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Wraps the passed-in iterator instance in a new iterator that displays state information about the current element when it is requested. |
Parameter | Description |
<name> | A string to be displayed to indicate meaningful information when displaying the current element. |
<iterator> | The iterator to wrap with the returned trace-iterator. |
Examples
> (define chatty-list (trace-iterator "chatty-list" (get-iterator '(1 2 3 4)))) > (foreach item in chatty-list . (display item) . (newline)) chatty-list -> 1 1 chatty-list -> 2 2 chatty-list -> 3 3 chatty-list -> 4 4 > |
Wrapping an existing iterator in a trace-iterator is possibly useful for debugging, but definitely not for production use. Professional logging techniques are recommended for production systems.
Signature | (iterator->list <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Converts an iterator to a proper list. |
Parameter | Description |
<iterator> | The iterator to be converted into a proper list. |
Examples
> (define it (get-iterator '(1 2 3 4))) > it #<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator> > (iterator->list it) (1 2 3 4) > |
Useful when returning a value from a function that uses LINQ to filter a collection. Most Scheme consumers will want a list or a vector of the results.
Signature | (iterator->vector <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Converts an iterator to a vector. |
Parameter | Description |
<iterator> | The iterator to be converted into a vector. |
Examples
> (define it (get-iterator '(1 2 3 4))) > it #<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator> > (iterator->vector it) #(1 2 3 4) > |
Useful when returning a value from a function that uses LINQ to filter a collection. Most Scheme consumers will want a list or a vector of the results.
Signature | (iterator->string <char-iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Given an iterator of chars, returns a string. |
Parameter | Description |
<chariterator> | The iterator of chars to be converted into a string. |
Examples
> (define chars (get-iterator '(#\f #\o #\o))) > chars #<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator> > (iterator->string chars) "foo" > |
Useful when converting results of queries on character iterators.
Signature | (iterator->hashtable <iterator> [<selector-function>]) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Given a hashtable iterator, returns a copy of the underlying hashtable. |
Parameter | Description |
<iterator> | The hashtable iterator from which we wish to extract a copy of the underlying hashtable. |
<selector-function> | [Optional] A function to obtain the key/value pair when iterating the entries in a hashtable. If not provided a simple default selector is used. |
Examples
> (import (visualscheme data linq)) > (compile) > (define ht (make-hashtable string-hash string=?)) > (hashtable-set! ht "Fee" 1) > (hashtable-set! ht "Fi" 2) > (hashtable-set! ht "Fo" 3) > (hashtable-set! ht "Fum" 4) > (define hti (get-iterator ht)) > (define (hashtable-entry->tuple entry) . (values (car entry) (cdr entry))) > (define ht-copy (iterator->hashtable hti hashtable-entry->tuple)) > (hashtable-ref ht-copy "Fum" 0) 4 > |
Obtaining a copy of the underlying data structure when that structure is a hashtable requires a way to iterate each key value pair and add them to a new hashtable copy. The example (hashtable-entry->tuple) function to select the key-value pair values does exactly this. Indeed, this is the default implementation we provide, so ordinarily you won’t need to provide this optional <selector> parameter unless, based on the data you stored in the original keys, you need more exotic processing of the key-value pair, for example: you want the new hashtable to be something other than an exact copy.
Signature | (iterator-move-next <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Given an iterator, it attempts to move to the “next” item in the underlying data structure, if one exists. |
Parameter | Description |
<iterator> | The iterator whose next item we seek to move to. |
Examples
> (iterator-reset hti) > (iterator-move-next hti) #t > (iterator-current hti) ("Fee" . 1) > (iterator-move-next hti) #t > (iterator-current hti) ("Fo" . 3) > (iterator-move-next hti) #t > (iterator-current hti) ("Fi" . 2) > (iterator-move-next hti) #t > (iterator-current hti) ("Fum" . 4) > (iterator-move-next hti) #f > |
The iterator-* functions tend to be used together. The (iterator-move-next <iterator>) function will advance to the “next” item, and return #t if successful, #f if there are no more items left to iterate.
Signature | (iterator-current <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Returns the current item in the underlying data structure being iterated, if any. |
Parameter | Description |
<iterator> | The iterator whose next item we seek to move to. |
Examples
> (iterator-reset hti) > (iterator-move-next hti) #t > (iterator-current hti) ("Fee" . 1) > (iterator-move-next hti) #t > (iterator-current hti) ("Fo" . 3) > (iterator-move-next hti) #t > (iterator-current hti) ("Fi" . 2) > (iterator-move-next hti) #t > (iterator-current hti) ("Fum" . 4) > (iterator-move-next hti) #f > |
The iterator-* functions tend to be used together. (iterator-current <iterator>) will return the current value after the most recent call to (iterator-move-next <iterator>).
Signature | (iterator-reset <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Procedure with a side effect |
Description | If successful, it repositions the iterator at the beginning of the underlying data structure. Note, not all iterator types support this function in the same way, especially if the underlying iterator is a .NET collection. |
Parameter | Description |
<iterator> | The iterator we seek to reset or otherwise position at the beginning of the underlying data structure. |
Examples
> (iterator-reset hti) > (iterator-move-next hti) #t > (iterator-current hti) ("Fee" . 1) > (iterator-move-next hti) #t > (iterator-current hti) ("Fo" . 3) > (iterator-move-next hti) #t > (iterator-current hti) ("Fi" . 2) > (iterator-move-next hti) #t > (iterator-current hti) ("Fum" . 4) > (iterator-move-next hti) #f > |
The iterator-* functions tend to be used together. (iterator-reset <iterator>) restores the iterator to the initial position so the underlying collection can be iterated again. It doesn’t work as expected for all iterator types, especially those based on .NET collections, which are notoriously inconsistent in their interpretation of/support for resetting iterators.
Signature | (select <x> <selector>) |
Exported From | (visualscheme data linq) |
Type of Form | Function and keyword |
Description | You are unlikely (not to say discouraged) to use this function directly. It’s part of the domain-specific language we call “LINQ” and is intended for internal use in syntax extensions that comprise the iterator framework. |
Use select as a keyword in LINQ queries but not directly.
Signature | (select-many <x> <selector>) |
Exported From | (visualscheme data linq) |
Type of Form | Function and keyword |
Description | You are unlikely (not to say discouraged) to use this function directly. It’s part of the domain-specific language we call “LINQ” and is intended for internal use in syntax extensions that comprise the iterator framework. |
Use select-many as a keyword in LINQ queries but not directly
Signature | (where <x> <proc>) |
Exported From | (visualscheme data linq) |
Type of Form | Function and keyword |
Description | You are unlikely (not to say discouraged) to use this function directly. It’s part of the domain-specific language we call “LINQ” and is intended for internal use in syntax extensions that comprise the iterator framework. |
Use where as a keyword in LINQ queries but not directly.
Signature | (reverse-iterator <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Obtains a copy of the underlying data structure of the provided <iterator>, reverses its order, and then wraps it in a new iterator. |
Parameter | Description |
<iterator> | The iterator or iterable collection, the order of which you wish to reverse. |
Examples
> (define lst '(1 2 3 4)) > (define lst-iter (get-iterator lst)) > (define reverse-lst-iter (reverse-iterator lst-iter)) > (foreach i in reverse-lst-iter . (display i) . (newline)) 4 3 2 1 > |
If you have access to the original collection, you can of course call the appropriate flavor of (reverse! …) on it, and then call (get-iterator …) on the result of that; but if you have the iterator for the list, (reverse-iterator …) will save you a couple extra steps.
Signature | (single <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | If the <iterator> contains exactly one element, returns that element; otherwise throws an assertion violation. |
Parameter | Description |
<iterator> | The iterator on or iterable collection which the predicate is being invoked. |
Examples
> (single '(1)) 1 > (single '()) Unhandled exception during evaluation: &assertion &who: single &message: "contains no elements" &irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)
> (single '(1 2 3 4)) Unhandled exception during evaluation: &assertion &who: single &message: "contains more than one element" &irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)
> |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (single/default <iterator> <default-value>) |
Exported From | (visualscheme data linq) |
Type of Form | Function |
Description | Similar to (single <iterator>) except returns the default value if the iterator is empty. Otherwise, it throws an assertion violation. |
Parameter | Description |
<iterator> | The iterator or iterable collection on which the predicate is being invoked. |
Examples
> (single/default '() 0) 0 > (single/default '(1) 0) 1 > (single/default '(1 2 3 4) 0) Unhandled exception during evaluation: &assertion &who: single/default &message: "contains more than one element" &irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)
> |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (first <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Returns the first element of the passed-in iterator. Throws assertion violation if iterator is empty. |
Parameter | Description |
<iterator> | The iterator or iterable collection whose first element you seek. |
Examples
> (first '(1 2 3 4)) 1 > (first '()) Unhandled exception during evaluation: &assertion &who: first &message: "contains no elements" &irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)
> |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (first/default <iterator> <default-value>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Returns the first value of the passed-in <iterator>, or the desired <default-value> when it’s empty. |
Parameter | Description |
<iterator> | The iterator or iterable collection whose first value you seek. |
<default-value> | The default value to return if the iterator is empty. |
Examples
> (first/default '(1 2 3 4) 0) 1 > (first/default '() 0) 0 > |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (last <iterator>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Returns the last element of the passed in <iterator>. Throws an assertion violation if the iterator is empty. |
Parameter | Description |
<iterator> | The iterator or iterable collection whose last element you seek. |
Examples
> (last '(1 2 3 4)) 4 > (last '()) Unhandled exception during evaluation: &assertion &who: last &message: "contains no elements" &irritants: (())
> |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (last/default <iterator> <default-value>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Similar to (last …) except returns the provided default value if the iterator is empty. |
Parameter | Description |
<iterator> | The iterator or iterable collection whose last element you seek. |
<default-value> | The default value to return if the iterator is empty. |
Examples
> (last/default '(1 2 3 4) 0) 4 > (last/default '() 0) 0 > |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (element-at <iterator> <index>) |
Exported From | (visualscheme data linq) |
Type of Form | function |
Description | Returns the element from the iterator or iterable collection provided, or an error if the index is out of range. |
Parameter | Description |
<iterator> | The iterator or iterable collection whose value at <index> n is desired. |
<index> | The base-0 index at which position the desired element is found. |
Examples
> (element-at '(1 2 3 4) 2) 3 > (element-at '() 2) Unhandled exception during evaluation: &assertion &who: element-at &message: "index out of range" &irritants: (() 2) |
This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.
Signature | (foreach <var> in <iterator> body …) |
Exported From | (visualscheme data linq) |
Type of Form | Syntax extension |
Description | Similar to foreach semantics in C#. This syntax extension allows you to step eagerly element by element through an iterator or iterable collection and perform some action on the “current” element. |
Parameter | Description |
<var> | The name to give to the current element of the <iterator> to be used in the <body> of the expression. |
<iterator> | The iterator (or iterable collection) through which one intends to operate on each element one at a time, eagerly. Note, this can be an iterator result from complex linq query expressions. Note also that when working with an iterable collection, an iterator will be created behind the scenes. |
body | The block representing the expression to evaluate with each step through the iterator/iterable collection. |
Examples
> (define ht (make-hashtable string-hash string=?)) > (hashtable-set! ht "Foo" "bar") > (hashtable-set! ht "Baz" "qux") > (foreach entry in ht . (display (string-append (car entry) " => " (cdr entry))) . (newline)) Foo => bar Baz => qux > (foreach i in '(1 2 3 4) . (display i) . (newline)) 1 2 3 4 > |
Similar to the built-in (for-each <fn> <list>) except it works with any iterable collection as supported in (visualscheme data linq). Compare:
> (for-each (lambda (entry) . (display entry) . (newline)) . '(1 2 3 4)) 1 2 3 4 > (for-each (lambda (entry) . (display (string-append (car entry) " => " (cdr entry))) . (newline)) . ht) Unhandled exception during evaluation: &assertion &who: "car" &message: "not a pair" &irritants: (#<hashtable>)
> |
Not only is (foreach …) syntax nicer and more flexible, it is also more broadly applicable. (for-each …) requires a lambda expression, and only accepts a list for input.
Additional Available (visualscheme data linq) Functions
The following list of functions are used internally in LINQ but you may find them useful. Each of these are exported from the (visualscheme data linq) library and are provided here for reference. For examples of practical LINQ usage, see Practical LINQ Examples.
Form Name | Signature | Description |
element-at/default | (element-at/default <iterator> <index> <default-value>) | Gets the element at a specified index. Returns default when index is out of bounds. |
count | (count iter) | Returns the number of elements in the iterator. |
range | (range end) | Returns an iterator of numbers starting with 0, incrementing 1, up to, but excluding 'end'. |
aggregate | (aggregate iter init proc) | Also known as fold-left. Procedure takes 2 args (accumulator and element) and returns a single value. |
concat | (concat iter1 iter2) | Return an iterator for the concatenation of both iterators. |
any? | (any? iter pred) | Also known as exists. |
all? | (all? iter pred) | Also known as for-all. |
empty | (empty) | Returns an empty iterator (singleton). |
empty? | (empty? iter) | Tests if an iterator is empty (contains no elements). |
repeat | (repeat obj count) | Returns an iterator that contains one repeated value, for count number of times. |
average | (average iter) | Gets the average of an iterable of numbers. |
maximum | (maximum iter) | Returns the maximum element of an iterator. Must be a number. |
minimum | (minimum iter) | Returns the minimum element of an iterator. Must be a number. |
sum | (sum iter) | Gets the sum of an iterable of numbers. |
take | (take count iter) | Returns an iterator that takes the count number of elements of an iterator. Returns an empty iterator if the count is smaller than the count of the iterator. |
skip | (skip count iter) | Returns an iterator that skips the count number of elements of an iterator. Returns an empty iterator if the count is smaller than the count of the iterator. |
iterator=? | (iterator=? iter1 iter2) | Determines whether two iterators are equal by comparing the elements. |
distinct | (distinct iter) | Returns an iterator of distinct elements of iter. |
union | (union iter1 iter2) | Returns an iterator that contains the elements from both iterators, excluding duplicates. |
except | (except iter1 iter2) | Returns an iterator that contains the set difference of the elements of two iterators. |
intersect | (intersect iter1 iter2) | Returns an iterator that contains the elements that form the set intersection of two iterators. |
grouping? | (grouping? obj) | Returns an iterator that contains the elements that form the set intersection of two iterators. |
from | - | Tests whether an object is a grouping. |
The following terms are registered trademarks of the Microsoft group of companies and are used in accordance with Microsoft’s Trade and Brand Guidelines: Microsoft, Microsoft 365, Microsoft Office, Microsoft Excel, Microsoft Edge, Microsoft Edge WebView2, Microsoft Windows, Excel, Office 365
Copyright © 2022. Apex Data Solutions, LLC. All Rights Reserved.