Just found I’ve made a completely invalid assumpti...
# announcements
r
Just found I’ve made a completely invalid assumption about
singleOrNull
- I assumed it would throw an exception if size > 1, but it returns null.
I’d quite like something that asserts an
Iterable<T>
has 0..1 elements by returning a
T?
or throwing an exception if size > 1.
(what’s the term for the types of numbers in a collection?
0
,
1
,
0..1
,
0..*
,
1..*
- it’s not arity…)
t
Shouldn’t you used Optional instead if you got a construct like that?
Normally I’m choosing
first()
for sth. like that. Or i’m simply asserting that the collection size is less-equal 1. But don’t quite understand the reason to choose Collection if you are just having zero or exactly one value(s)?
r
@Rob Elliot this function may do what you want:
Copy code
fun <A> Iterable<A>.firstOrThrow(): A =
  if (size > 1) throw IllegalStateException("unexpected size == $size. $this")
  else first()
but as @Timo Gruen said maybe if you have a data structure that can only contain a single potentially absent element then nullable types it’s a better option.
r
I’m filtering an Iterable to one or zero.
y
To add to raulraja's suggestion this possibly fits better with your usecase:
Copy code
fun <A> Iterable<A>.singleOrThrow(): A? =
  if (size > 1) throw IllegalStateException("unexpected size == $size. $this")
  else firstOrNull() // Returns A if size == 1 and null if size == 0
r
Thanks all - it’s not a problem with writing the function, just surprise at the original one’s behaviour (though as I think about it, it is consistent with other xOrNull behaviour). (I’s the
singleOrNull(predicate: (T) -> Boolean)
that I was using btw)