blob: 0da319735fddeac85b0af4e24e17bb30523eb53a [file] [log] [blame]
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--><head>
<meta charset='utf-8'/><meta http-equiv='X-UA-Compatible' content='IE=edge'/><meta name='viewport' content='width=device-width, initial-scale=1'/><meta name='keywords' content='groovy, collections, zip, eclipse collections, guava, vavr, streamex, jOOλ, ginq, gquery, emoji'/><meta name='description' content='This post looks at zipping collections.'/><title>The Apache Groovy programming language - Blogs - Zipping Collections with Groovy</title><link href='../img/favicon.ico' type='image/x-ico' rel='icon'/><link rel='stylesheet' type='text/css' href='../css/bootstrap.css'/><link rel='stylesheet' type='text/css' href='../css/font-awesome.min.css'/><link rel='stylesheet' type='text/css' href='../css/style.css'/><link rel='stylesheet' type='text/css' href='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css'/>
</head><body>
<div id='fork-me'>
<a href='https://github.com/apache/groovy'>
<img style='position: fixed; top: 20px; right: -58px; border: 0; z-index: 100; transform: rotate(45deg);' src='/img/horizontal-github-ribbon.png'/>
</a>
</div><div id='st-container' class='st-container st-effect-9'>
<nav class='st-menu st-effect-9' id='menu-12'>
<h2 class='icon icon-lab'>Socialize</h2><ul>
<li>
<a href='https://groovy-lang.org/mailing-lists.html' class='icon'><span class='fa fa-envelope'></span> Discuss on the mailing-list</a>
</li><li>
<a href='https://twitter.com/ApacheGroovy' class='icon'><span class='fa fa-twitter'></span> Groovy on Twitter</a>
</li><li>
<a href='https://groovy-lang.org/events.html' class='icon'><span class='fa fa-calendar'></span> Events and conferences</a>
</li><li>
<a href='https://github.com/apache/groovy' class='icon'><span class='fa fa-github'></span> Source code on GitHub</a>
</li><li>
<a href='https://groovy-lang.org/reporting-issues.html' class='icon'><span class='fa fa-bug'></span> Report issues in Jira</a>
</li><li>
<a href='http://stackoverflow.com/questions/tagged/groovy' class='icon'><span class='fa fa-stack-overflow'></span> Stack Overflow questions</a>
</li><li>
<a href='http://groovycommunity.com/' class='icon'><span class='fa fa-slack'></span> Slack Community</a>
</li>
</ul>
</nav><div class='st-pusher'>
<div class='st-content'>
<div class='st-content-inner'>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]--><div><div class='navbar navbar-default navbar-static-top' role='navigation'>
<div class='container'>
<div class='navbar-header'>
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
<span class='sr-only'></span><span class='icon-bar'></span><span class='icon-bar'></span><span class='icon-bar'></span>
</button><a class='navbar-brand' href='../index.html'>
<i class='fa fa-star'></i> Apache Groovy
</a>
</div><div class='navbar-collapse collapse'>
<ul class='nav navbar-nav navbar-right'>
<li class=''><a href='https://groovy-lang.org/learn.html'>Learn</a></li><li class=''><a href='https://groovy-lang.org/documentation.html'>Documentation</a></li><li class=''><a href='/download.html'>Download</a></li><li class=''><a href='https://groovy-lang.org/support.html'>Support</a></li><li class=''><a href='/'>Contribute</a></li><li class=''><a href='https://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li class=''><a href='/blog'>Blog posts</a></li><li class=''><a href='https://groovy.apache.org/events.html'></a></li><li>
<a data-effect='st-effect-9' class='st-trigger' href='#'>Socialize</a>
</li><li class=''>
<a href='../search.html'>
<i class='fa fa-search'></i>
</a>
</li>
</ul>
</div>
</div>
</div><div id='content' class='page-1'><div class='row'><div class='row-fluid'><div class='col-lg-3'><ul class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a href='#doc'>Zipping Collections with Groovy</a></li><li><a href='#_what_is_zipping' class='anchor-link'>What is zipping?</a></li><li><a href='#_groovy' class='anchor-link'>Groovy</a></li><li><a href='#_eclipse_collections' class='anchor-link'>Eclipse Collections</a></li><li><a href='#_guava' class='anchor-link'>Guava</a></li><li><a href='#_streamex' class='anchor-link'>StreamEx</a></li><li><a href='#_vavr' class='anchor-link'>Vavr</a></li><li><a href='#_jooλ' class='anchor-link'>jOOλ</a></li><li><a href='#_groovy_gquery' class='anchor-link'>Groovy GQuery</a></li><li><a href='#_more_information' class='anchor-link'>More information</a></li></ul><br/><ul class='nav-sidebar'><li style='padding: 0.35em 0.625em; background-color: #eee'><span>Related posts</span></li><li><a href='./groovy-list-processing-cheat-sheet'>Groovy List Processing Cheat Sheet</a></li><li><a href='./groovy-null-processing'>Groovy Processing Nulls In Lists</a></li><li><a href='./parsing-json-with-groovy'>Parsing JSON with Groovy</a></li><li><a href='./deep-learning-and-eclipse-collections'>Deep Learning and Eclipse Collections</a></li><li><a href='./comparators-and-sorting-in-groovy'>Comparators and Sorting in Groovy</a></li><li><a href='./wordle-checker'>Checking Wordle with Groovy</a></li><li><a href='./fruity-eclipse-collections'>Fruity Eclipse Collections</a></li><li><a href='./adventures-with-groovyfx'>Adventures with GroovyFX</a></li><li><a href='./deck-of-cards-with-groovy'>Deck of cards with Groovy, JDK collections and Eclipse Collections</a></li><li><a href='./lego-bricks-with-groovy'>Lego Bricks with Groovy</a></li><li><a href='./groovy-haiku-processing'>Groovy Haiku processing</a></li><li><a href='./helloworldemoji'>Hello World with Emojis</a></li></ul></div><div class='col-lg-8 col-lg-pull-0'><a name='doc'></a><h1>Zipping Collections with Groovy</h1><p><span>Author: <i>Paul King</i></span><br/><span>Published: 2022-11-17 12:50PM</span></p><hr/><div class="sect1">
<h2 id="_what_is_zipping">What is zipping?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In computer science, <a href="https://en.wikipedia.org/wiki/Zipping_(computer_science)">zipping</a> translates sequences into sequences where, if visualized in two dimensions, the rows and columns are swapped. So the zip of:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="groovy">[['a', 'b', 'c'],
[ 1 , 2 , 3 ]]</code></pre>
</div>
</div>
<div class="paragraph">
<p>would be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="groovy">[['a', 1],
['b', 2],
['c', 3]]</code></pre>
</div>
</div>
<div class="paragraph">
<p>It&#8217;s a very handy operation and depending on the language, may be supported for tuples, lists, streams and other sequences or aggregates.</p>
</div>
<div class="paragraph">
<p>Java collections and streams don&#8217;t currently support such functionality out-of-the-box with various workarounds discussed <a href="https://dzone.com/articles/bridge-the-gap-of-zip-operation">here</a>. The summary: language and library design is hard; any zip implementation that Java provides would have some limitations baked in, so they instead provide the necessary primitives to allow folks to build their own implementations based on their specific requirements.</p>
</div>
<div class="paragraph">
<p>We&#8217;ll look at what Groovy provides and some of the available Java libraries that you can also use. The same caveats apply to these libraries, each will have its own implementation strengths and weaknesses.</p>
</div>
<div class="paragraph">
<p>We&#8217;ll use an example inspired by this <a href="https://twitter.com/TheDonRaab">Donald Raab</a> <a href="https://donraab.medium.com/make-or-append-me-a-string-c654f247373a">blog post</a>. It looks at zipping (and formatting) lists of strings containing "fall"-inspired emoji. Yes, it&#8217;s late spring for the southern hemisphere who also mostly call fall "autumn", but hopefully everyone will appreciate the inspiration.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/fall_emojis.png" alt="some fall inspired emojis" width="741"></span></p>
</div>
<hr>
</div>
</div>
<div class="sect1">
<h2 id="_groovy">Groovy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Groovy uses the <code>transpose</code> method for zipping:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsGroovy.png" alt="zipping example with Groovy"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_eclipse_collections">Eclipse Collections</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Eclipse Collections has a <code>zip</code> method on its list classes:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsEC.png" alt="zipping example with Eclipse Collections"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_guava">Guava</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Guava has a streams utility class with a <code>zip</code> method:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsGuava.png" alt="zipping example with Guava"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_streamex">StreamEx</h2>
<div class="sectionbody">
<div class="paragraph">
<p>StreamEx provides an enhanced stream library which supports <code>zipWith</code>:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsStreamEx.png" alt="zipping example with StreamEx"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_vavr">Vavr</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vavr has a <code>zipWith</code> method on its list class:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsVavr.png" alt="zipping example with Vavr"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_jooλ">jOOλ</h2>
<div class="sectionbody">
<div class="paragraph">
<p>jOOλ has a <code>zip</code> method for its sequences:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsJool.png" alt="zipping example with jOOλ"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_groovy_gquery">Groovy GQuery</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you are a fan of query-like DSLs, Groovy&#8217;s language integrated query, GQuery (AKA GINQ), can also be used:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/ZippingCollectionsGQ.png" alt="zipping example with GQuery"></span></p>
</div>
<div class="paragraph">
<p>This uses a special <code>_rn</code> "row number" pre-defined variable in GQ expressions. It follows the same strategy as the IntStream "workaround" for Java mentioned in this <a href="https://www.baeldung.com/java-collections-zip">blog</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_more_information">More information</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The code examples can be found in the <a href="https://github.com/paulk-asert/zipping-collections">repo</a></p>
</div>
</div>
</div></div></div></div></div><footer id='footer'>
<div class='row'>
<div class='colset-3-footer'>
<div class='col-1'>
<h1>Groovy</h1><ul>
<li><a href='https://groovy-lang.org/learn.html'>Learn</a></li><li><a href='https://groovy-lang.org/documentation.html'>Documentation</a></li><li><a href='/download.html'>Download</a></li><li><a href='https://groovy-lang.org/support.html'>Support</a></li><li><a href='/'>Contribute</a></li><li><a href='https://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li><a href='/blog'>Blog posts</a></li><li><a href='https://groovy.apache.org/events.html'></a></li>
</ul>
</div><div class='col-2'>
<h1>About</h1><ul>
<li><a href='https://github.com/apache/groovy'>Source code</a></li><li><a href='https://groovy-lang.org/security.html'>Security</a></li><li><a href='https://groovy-lang.org/learn.html#books'>Books</a></li><li><a href='https://groovy-lang.org/thanks.html'>Thanks</a></li><li><a href='http://www.apache.org/foundation/sponsorship.html'>Sponsorship</a></li><li><a href='https://groovy-lang.org/faq.html'>FAQ</a></li><li><a href='https://groovy-lang.org/search.html'>Search</a></li>
</ul>
</div><div class='col-3'>
<h1>Socialize</h1><ul>
<li><a href='https://groovy-lang.org/mailing-lists.html'>Discuss on the mailing-list</a></li><li><a href='https://twitter.com/ApacheGroovy'>Groovy on Twitter</a></li><li><a href='https://groovy-lang.org/events.html'>Events and conferences</a></li><li><a href='https://github.com/apache/groovy'>Source code on GitHub</a></li><li><a href='https://groovy-lang.org/reporting-issues.html'>Report issues in Jira</a></li><li><a href='http://stackoverflow.com/questions/tagged/groovy'>Stack Overflow questions</a></li><li><a href='http://groovycommunity.com/'>Slack Community</a></li>
</ul>
</div><div class='col-right'>
<p>
The Groovy programming language is supported by the <a href='http://www.apache.org'>Apache Software Foundation</a> and the Groovy community.
</p><div text-align='right'>
<img src='../img/asf_logo.png' title='The Apache Software Foundation' alt='The Apache Software Foundation' style='width:60%'/>
</div><p>Apache&reg; and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
</div>
</div><div class='clearfix'>&copy; 2003-2023 the Apache Groovy project &mdash; Groovy is Open Source: <a href='http://www.apache.org/licenses/LICENSE-2.0.html' alt='Apache 2 License'>license</a>, <a href='https://privacy.apache.org/policies/privacy-policy-public.html'>privacy policy</a>.</div>
</div>
</footer></div>
</div>
</div>
</div>
</div><script src='../js/vendor/jquery-1.10.2.min.js' defer></script><script src='../js/vendor/classie.js' defer></script><script src='../js/vendor/bootstrap.js' defer></script><script src='../js/vendor/sidebarEffects.js' defer></script><script src='../js/vendor/modernizr-2.6.2.min.js' defer></script><script src='../js/plugins.js' defer></script><script src='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js'></script><script>document.addEventListener('DOMContentLoaded',prettyPrint)</script><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-257558-10', 'auto');
ga('send', 'pageview');
</script>
</body></html>