maidh91 / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

A way to get a Function that looks up counts in a Multiset #419

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Either: Function<E, Integer> Multisets.countFunction (Multiset<? extends E> 
multiset);

Or: Map<E, Integer> Multisets.asMap(Multiset<? extends E> multset); So that I 
can then run the resulting map through Functions.forMap(). Presumably the Map 
view would return null if the count for an element was 0, which is a little 
odd, but otherwise the size() of the Map wouldn't make any sense. So maybe the 
first one is better.

Original issue reported on code.google.com by ray.j.gr...@gmail.com on 15 Sep 2010 at 7:14

GoogleCodeExporter commented 9 years ago
Whoops, both of those should be Multiset<? super E>, right? Although since 
count() takes an Object I suppose it could just be Multiset<?>.

Original comment by ray.j.gr...@gmail.com on 16 Sep 2010 at 1:05

GoogleCodeExporter commented 9 years ago
If the argument was a Multiset<E> (not ? extends E or ? super E) then it could 
support
Multisets.asMap(multiset).put(element, newCount)

Original comment by fin...@gmail.com on 27 Sep 2010 at 1:45

GoogleCodeExporter commented 9 years ago
I guess there are two different issues here:

I wanted a count function so that I could transform entries to ints. I have 
already made this on my own: Function<Object, Integer> countFunction 
(Multiset<?> set); Since any object can be safely looked up.

Alternatively, if there were a way to view a Multiset<E> as a Map<E, Integer> 
then the existing Functions.forMap() could be used. And yes, you could modify 
the backing Multiset using standard Map-aware code.

Original comment by ray.j.gr...@gmail.com on 27 Sep 2010 at 5:48

GoogleCodeExporter commented 9 years ago
I think there is value to both suggestions: asFunction()/countFunction() and 
asMap()/countMap().

Original comment by boppenh...@google.com on 27 Sep 2010 at 6:34

GoogleCodeExporter commented 9 years ago
The count function seems innocuous.  Multisets.countFunction() is a decent 
enough name I think.

I've actively resisted the view-multiset-as-map idea.  I'd rather hear all the 
things users sometimes want that for, and see in each case if there's a better 
solution to suggest or provide.

Original comment by kevinb@google.com on 19 Mar 2011 at 3:10

GoogleCodeExporter commented 9 years ago

Original comment by kevinb@google.com on 13 Jul 2011 at 6:18

GoogleCodeExporter commented 9 years ago

Original comment by cpov...@google.com on 13 Jul 2011 at 8:59

GoogleCodeExporter commented 9 years ago

Original comment by kevinb@google.com on 18 Jul 2011 at 4:05

GoogleCodeExporter commented 9 years ago

Original comment by fry@google.com on 10 Dec 2011 at 3:48

GoogleCodeExporter commented 9 years ago

Original comment by fry@google.com on 16 Feb 2012 at 7:17

GoogleCodeExporter commented 9 years ago
I'd like a Multisets.asMap so that a multiset can be easily converted for use 
with tools that know how to serialize maps. For example, with Jackson:

new 
ObjectMapper().writeValueAsString(Multisets.asMap(ImmutableMultiset.of("foo", 
"foo", "bar")))

> {"foo": 2, "bar": 1}

Original comment by inetper...@gmail.com on 1 Mar 2012 at 7:36

GoogleCodeExporter commented 9 years ago
Can we find some way to do this with Jackson without viewing a Multiset as a 
Map?  I agree with Kevin that view-multiset-as-a-map is a bad idea.

Original comment by wasserman.louis on 1 Mar 2012 at 7:49

GoogleCodeExporter commented 9 years ago
Does Kevin say anywhere *why* he opposes this?

Original comment by inetper...@gmail.com on 1 Mar 2012 at 7:55

GoogleCodeExporter commented 9 years ago
See comment 5.  I don't "oppose" it; I consider the jury to be out.  Every time 
this comes up, it has never turned out to be the best solution.

Can't this Jackson support custom data types?

Original comment by kevinb@google.com on 1 Mar 2012 at 4:21

GoogleCodeExporter commented 9 years ago

Original comment by kevinb@google.com on 30 May 2012 at 7:43

GoogleCodeExporter commented 9 years ago

Original comment by kevinb@google.com on 22 Jun 2012 at 6:16

GoogleCodeExporter commented 9 years ago
Probably much too late, but it would be nice to be able to quickly define an 
ordering based on count like: 

Ordering<E> ordering = 
Ordering.natural().onResultOf(Multisets.countFunction(m));

Which would allow you to quickly and concisely get the most common result, 
greatest N, etc.

Original comment by jmschei...@google.com on 14 Aug 2014 at 2:35

GoogleCodeExporter commented 9 years ago
It would be helpful to have some way to expose the list of counts for a given 
Multiset; right now there is no way to do that easily, without iterating over 
the multiset's elements or over the result of entrySet().  So for example, if I 
have a multiset and want to get the count of the most frequent element - just 
that, I don't care what that element is - there isn't a particularly good way 
to do it.

My first instinct was to go with 
Ordering.natural().max(multiset.asMap().values()), but asMap() does not exist.  
FWIW I don't see any real reason why view-multiset-as-a-map is a bad idea.

Original comment by nickf...@google.com on 1 Oct 2014 at 8:18

GoogleCodeExporter commented 9 years ago
This particular issue, relative to the Multimap-as-Map issue, seems like Java 8 
will make it pretty much irrelevant, for those users who have it available.  
I'd tend to write, for example, 
multiset.entrySet().stream().mapToInt(Entry::getCount).max() for that use case.

Original comment by lowas...@google.com on 1 Oct 2014 at 9:35

GoogleCodeExporter commented 9 years ago
The overall goal of finding the most common and greatest N results sounds like 
Multisets.copyHighestCountFirst. But I fear that there's some problem with that 
idea, since I would otherwise have expected Louis to suggest it :)

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect
/Multisets.html#copyHighestCountFirst%28com.google.common.collect.Multiset%29

Original comment by cpov...@google.com on 7 Oct 2014 at 4:02

GoogleCodeExporter commented 9 years ago
Right, I saw that, but you'd need something like

Iterables.get(Multisets.copyHighestCountFirst(multiset).entrySet(), 
0).getCount()

which just seemed really indirect and hard to understand on a first read.

Also, although in my particular case I'm not that worried about performance, if 
I was it doesn't seem like copyHighestCountFirst() would be a good strategy 
since unless I'm mistaken that always sorts the whole set of entries (nlogn vs 
n to find the max).

Original comment by nickf...@google.com on 7 Oct 2014 at 5:54

GoogleCodeExporter commented 9 years ago
If I were going to do it like that, it'd be 
Multisets.copyHighestCountFirst(multiset).entrySet().asList().get(0).getCount(),
 since you've got the cheap asList() view.  The issue of sorting the whole 
thing is why I didn't suggest that, though.

Original comment by lowas...@google.com on 7 Oct 2014 at 5:56

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:15

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:18

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:09