I've got two List
objects and I want to pair them up, just like the zip()
function in Python. I'm pretty sure this isn't available in the JDK, but is there something like this in a fairly widespread library, similar to Apache Commons Collections? Thanks.
views:
207answers:
2
+2
A:
Functional Java has zip
, zipWith
and zipIndex
the way you would expect from Haskell or Scala. (Indeed, the authors are pretty much all Haskell programmers.)
Jörg W Mittag
2010-01-22 17:37:09
All those angle brackets in the method signature probably explain why there is no *widespread* solution in Java.
Mirko Nasato
2010-01-22 17:41:56
holy crap, you're right: `public static <A,B,C> F<List<A>,F<List<B>,F<F<A,F<B,C>>,List<C>>>> zipWith()` -- are they going for comedy value??
Kevin Bourrillion
2010-01-23 00:27:04
Actually, the version I linked to is the first-class version. (I couldn't figure out how to link to the other version without Markdown gobbling up the link.) IOW: it's not the `zipWith` *function* it's a function that *returns* the `zipWith` function. The signature for the *real* `zipWith` is `public <B,C> List<C> zipWith(List<B> bs, F2<A,B,C> f)`, which is basically the same as the Haskell one: `(a → b → c) → [a] → [b] → [c]`. It takes a list of as (the implicit `this`), a list of bs and a function from a and b to c and returns a list of cs.
Jörg W Mittag
2010-01-24 11:19:33
Be thankful, they called the function interface `F2`! A Java programmer would've probably called it `FunctionWhichTakesTwoArgumentsAndReturnsOne` instead. Imagine what the type signature would look like then!
Jörg W Mittag
2010-01-24 11:20:58
A:
This is generally not a good idea! How did you end up getting this information as two separate lists? If you zip them together, what ensures that the right keys really are being paired up with the right values?
Every time I've gotten this question -- which is many times -- I've always pressed for what the user was "really trying to do", and every time I have been able to help them see a better way to do it. So, what are you really trying to do? Please give more context. Thanks.
Kevin Bourrillion
2010-01-22 23:11:42
There are many valid reasons to use a `zip` operation, in many languages. Are you saying that Java is somehow uniquely unsuited to have this useful tool? And what makes you think the object is to get key/value pairs?
Joel Mueller
2010-01-22 23:39:29
Sorry if I was wrong that the intent was to get a map. This is the problem with "I want a thing that's like X" questions -- anyone who doesn't know X in great detail doesn't really know what the question is about. If the user would actually explain what they're really trying to do, it would help (which is exactly what I'm asking for).
Kevin Bourrillion
2010-01-23 00:25:09
I have two lists that I want to operate on at the same time. Zipping them is much cleaner than writing the looping logic inline, especially if it needs to handle lists of different lengths (I do). The object is definitely not to get a Map. I agree, though, that getting a Map this way is bad.
Hank Gay
2010-01-23 21:21:56
The part that's still missing is where these two separate lists came from, and how you really know that the pairwise correspondence really exists.Or maybe this is just a simple case of displaying two columns in a UI or something.
Kevin Bourrillion
2010-01-25 22:13:49
@Kevin: One example I can think of is the iTunes music library xml format - it's kinda nasty: key node then value node then key node then value node... in sequence, so one easy way of mapping them is to grab the nodes as two lists (first node is `key`, others are various but never `key`) and then `zip` them. Bit of an edge case though, dealing with a dodgy third party format.
Jordan Stewart
2010-01-27 07:31:22
When I'm dealing with something like that, I put() each entry into my map as I go. Why "spread the data out" across two lists and then just need to "zip" it back together? It's never made sense to me.
Kevin Bourrillion
2010-01-28 16:42:28
If all you want is one set of items embedded a couple of levels deep in the xml then depending on what operations are available in your language of choice, it may be easier to grab each list separately. Although I guess you could grab the whole thing with a more general op and *then* iterate -- actually yeah, I guess if your language allows you to iterate two at a time then that would be the better solution :-)
Jordan Stewart
2010-02-02 22:36:49