-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add zip, zip-with and zip-all functions #15
base: master
Are you sure you want to change the base?
Conversation
Remove links to DRM for 'array', 'deque' and 'string'.
|
||
The function operates on two sequences (like :drm:`range`, | ||
`array`, :drm:`list`, `deque` or `string`) and | ||
transforms them in a :drm:`<sequence>` of pairs, each element from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make these references to the types: :drm:`<range>`
, :drm:`<vector>`
, :drm:`<list>`
, :drm:`<deque>`
, or :drm:`<string>`
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it, in a previous commit, but wrong. Thanks.
let b = #('a', 'b'); | ||
|
||
let zipped = zip(a, b); | ||
format-out("%=", zipped); // Output: #(#(1, 'a'), #(2, 'b')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, but I prefer the following style, because it doesn't have the distraction of the format-out
call.
let a = #(1, 2);
let b = #('a', 'b');
zip(a, b)
// => #(#(1, 'a'), #(2, 'b'))
:signature: | ||
|
||
zip-all (sequences) => (zipped) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zip-all #rest *sequences* => *zipped-sequence*
= map; | ||
|
||
define function zip-all | ||
(#rest sequences) => (zipped :: <sequence>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name "sequences" is misleading here since this function will only work with lists. Should it work with sequences in general? (I think so.) Perhaps you can do it by calling forward-iteration-protocol
on each sequence directly.
add(zipped, map(head, seqs))) | ||
end | ||
end; | ||
if (empty?(sequences)) #() else recur(sequences, #()) end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a big fan of the iterate
macro, which would look something like this:
define function zip-all (#rest lists) => (zipped :: <list>)
iterate loop (lists = lists, zipped = #())
if (any?(empty?, lists))
reverse!(zipped)
else
loop(map(tail, lists), pair(map(head, lists)))
end if
end iterate
end function
It basically combines the definition of the local method and the initial call to it.
@@ -588,3 +588,29 @@ define method precedes?(elt-1, elt-2, seq :: <sequence>, | |||
not-found; | |||
end block; | |||
end method precedes?; | |||
|
|||
define function zip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming is hard, so I won't claim that this is definitely better, but one potential alternative is to call this function zip2
and call zip-all
just zip
so that it matches other popular languages (Python).
No description provided.