@@ -233,23 +233,29 @@ ForderObj = function(x, starts=NULL, maxgrpn=NULL, anyna=0L, anyinfnan=0L, anyno
233233 x
234234}
235235
236- c_sortable_letters = letters
236+ c_sortable_pairs = apply(expand.grid( letters, letters), 1L, paste, collapse="")
237237# For some tests of forder() compatibility with base sorting methods.
238- # Subset the letters until the collation order matches C. This way we don't totally ignore
238+ # Subset the pairs of letters until the collation order matches C. This way we don't totally ignore
239239# any possible issues with sorting strings in unusual locales (even though this _should_
240240# be impossible given we _always_ use C-collated order, such a regression test is still
241- # beneficial as a sanity check).
242- if (!identical(order(letters, method='shell'), order(letters, method='radix'))) {
241+ # beneficial as a sanity check). Pairs of letters are needed for languages like Latvian which
242+ # have some '<='-like letters e.g. 'i' and 'y' are considered something of a 'tie', except when a
243+ # tie-breaker is needed. For example, 'ya' comes before 'ib' because of 'a' < 'b' and 'i' <= 'y',
244+ # but the letters alone sort as 'i' < 'y'.
245+ if (!identical(order(c_sortable_pairs, method='shell'), order(c_sortable_pairs, method='radix'))) {
243246 repeat {
244- sorted_c = c_sortable_letters [order(c_sortable_letters , method='radix')]
245- sorted_r = c_sortable_letters [order(c_sortable_letters , method='shell')]
247+ sorted_c = c_sortable_pairs [order(c_sortable_pairs , method='radix')]
248+ sorted_r = c_sortable_pairs [order(c_sortable_pairs , method='shell')]
246249
247250 mismatch = which(sorted_c != sorted_r)
248251 if (!length(mismatch)) break
249- c_sortable_letters = c_sortable_letters [-mismatch[1L]]
252+ c_sortable_pairs = c_sortable_pairs [-mismatch[1L]]
250253 }
254+ } else {
255+ # don't pull all 676 pairs, but also not sample() for stability
256+ c_sortable_pairs = c_sortable_pairs[seq(1L, length(c_sortable_pairs), length.out=75L)]
251257}
252- if (length(c_sortable_letters ) < 5L) {
258+ if (length(c_sortable_pairs ) < 5L) {
253259 stop("This locale collates too differently from C; please report.")
254260}
255261
@@ -4474,12 +4480,12 @@ test(1221, DT[.(1),b], c("a","c","e"))
44744480seed = as.integer(Sys.time()) # sample(9999L, 1L) temporary fix, because all the set.seed(.) used above makes this sample() step deterministic (always seed=9107)
44754481# no NaN (because it's hard to match with base::order); tested below in 1988.4-8
44764482set.seed(seed)
4477- foo <- function(n) apply(matrix(sample(c_sortable_letters , n*8L , TRUE), ncol=8L ), 1, paste, collapse="")
4483+ foo <- function(n) apply(matrix(sample(c_sortable_pairs , n*4L , TRUE), ncol=4L ), 1, paste, collapse="")
44784484i1 = as.integer(sample(c(-100:100), 1e3, TRUE))
44794485i2 = as.integer(sample(c(-100:100, -1e6, 1e6), 1e3, TRUE))
44804486d1 = as.numeric(sample(c(-100:100,Inf,-Inf), 1e3, TRUE))
44814487d2 = as.numeric(rnorm(1e3))
4482- c1 = sample(c_sortable_letters , 1e3, TRUE)
4488+ c1 = sample(c_sortable_pairs , 1e3, TRUE)
44834489c2 = sample(foo(50), 1e3, TRUE)
44844490
44854491DT = data.table(i1, i2, d1, d2, c1, c2)
@@ -4748,11 +4754,11 @@ seed = as.integer(Sys.time())
47484754# forder consistently to save pull requests failing coverage tests randomly, issue #2346
47494755set.seed(seed)
47504756# these variable try to simulate groups of length 1, 2, < 200, > 200 so as to cover all different internal implementations
4751- foo <- function(n) apply(matrix(sample(c_sortable_letters , n*8L , TRUE), ncol=8L ), 1, paste, collapse="")
4757+ foo <- function(n) apply(matrix(sample(c_sortable_pairs , n*4L , TRUE), ncol=4L ), 1, paste, collapse="")
47524758i1 = as.integer(sample(rep(c(-3:3, NA_integer_), c(1, 2, 190, 300, 7, 190, 210, 100))))
47534759i2 = as.integer(sample(rep(c(-2:2, -1e6, 1e6, NA_integer_), c(1, 2, 190, 300, 7, 190, 210, 100))))
47544760d1 = as.numeric(sample(rep(c(-2:2,Inf,-Inf, NA_real_, 5, -1e3), c(1, 190, 2, 300, 7, 50, 50, 100, 150, 150))))
4755- c1 = sample(rep(c(c_sortable_letters [1:5], NA_character_, "z"), c(1, 2, 190, 7, 300, 200, 300)))
4761+ c1 = sample(rep(c(c_sortable_pairs [1:5], NA_character_, "z"), c(1, 2, 190, 7, 300, 200, 300)))
47564762c2 = sample(c(foo(200), NA_character_), 1e3, TRUE)
47574763
47584764DT = data.table(i1, i2, d1, c1, c2)
0 commit comments