Skip to content

Commit a951897

Browse files
committed
Distinct, to produce an Iterable of distinct values in another Iterable
1 parent 80994bf commit a951897

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

β€ŽCHANGELOG.mdβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
1515
- `LiftA2` to lift and apply a `Bifunction` to two `Applicative`s
1616
- `Flatten` to lazily flatten nested `Iterable<Iterable<A>>`s to `Iterable<A>`
1717
- `Replicate`, short-hand composition of `take` and `repeat`
18+
- `Distinct` to produce an `Iterable` of distinct values in another `Iterable`
1819

1920
## [1.6.2] - 2017-08-20
2021
### Fixed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn1;
2+
3+
import com.jnape.palatable.lambda.functions.Fn1;
4+
5+
import java.util.HashMap;
6+
7+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Filter.filter;
8+
9+
/**
10+
* Return an {@link Iterable} of the distinct values from the given input {@link Iterable}.
11+
*
12+
* @param <A> the Iterable element type
13+
*/
14+
public final class Distinct<A> implements Fn1<Iterable<A>, Iterable<A>> {
15+
private static final Distinct INSTANCE = new Distinct();
16+
17+
private Distinct() {
18+
}
19+
20+
@Override
21+
public Iterable<A> apply(Iterable<A> as) {
22+
HashMap<A, Boolean> known = new HashMap<>();
23+
return filter(a -> known.putIfAbsent(a, true) == null, as);
24+
}
25+
26+
@SuppressWarnings("unchecked")
27+
public static <A> Distinct<A> distinct() {
28+
return INSTANCE;
29+
}
30+
31+
public static <A> Iterable<A> distinct(Iterable<A> as) {
32+
return Distinct.<A>distinct().apply(as);
33+
}
34+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn1;
2+
3+
import com.jnape.palatable.traitor.annotations.TestTraits;
4+
import com.jnape.palatable.traitor.runners.Traits;
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import testsupport.traits.EmptyIterableSupport;
8+
import testsupport.traits.FiniteIteration;
9+
import testsupport.traits.ImmutableIteration;
10+
import testsupport.traits.InfiniteIterableSupport;
11+
import testsupport.traits.Laziness;
12+
13+
import static com.jnape.palatable.lambda.functions.builtin.fn1.Distinct.distinct;
14+
import static java.util.Arrays.asList;
15+
import static org.junit.Assert.assertThat;
16+
import static testsupport.matchers.IterableMatcher.iterates;
17+
18+
@RunWith(Traits.class)
19+
public class DistinctTest {
20+
21+
@TestTraits({Laziness.class, InfiniteIterableSupport.class, EmptyIterableSupport.class, FiniteIteration.class, ImmutableIteration.class})
22+
public Distinct testSubject() {
23+
return distinct();
24+
}
25+
26+
@Test
27+
public void producesIterableOfOnlySingleElementOccurrences() {
28+
assertThat(distinct(asList(1, 2, 2, 3, 3, 3)), iterates(1, 2, 3));
29+
}
30+
}

0 commit comments

Comments
 (0)