code for #16 still needs to handle case where keyfn changes