Tatsuyuki Ishi
Tatsuyuki Ishi

Reputation: 4031

Is it possible to search a string with collator?

I'm currently creating a mechanism to filter items by a query string.

I want to convert this to locale-aware version (basically, case-ignorance in English, but also for Japanese Kana):

return items.filter((item) => {
  return item.name.indexOf(query) !== -1;
});

I have heard of ES6 Intl.Collation, and I would like to use it if it achieves my goal.

Upvotes: 7

Views: 528

Answers (1)

charlesroelli
charlesroelli

Reputation: 427

The following works for French, and it may carry over to Japanese too:

const collator = new Intl.Collator('en', { sensitivity: 'base', usage: 'search' });
function contains(string, substring) {
  if (substring.length === 0) {
    return true;
  }
  string = string.normalize('NFC');
  substring = substring.normalize('NFC');
  let scan = 0;
  for (; scan + substring.length <= string.length; scan += 1) {
    const slice = string.slice(scan, scan + substring.length);
    if (collator.compare(substring, slice) === 0) {
      return true;
    }
  }
  return false;
}

Eg.

contains("à point", "a point")
true

Cf. https://github.com/adobe/react-spectrum/blob/7f63e933e61f20891b4cf3f447ab817f918cb263/packages/%40react-aria/i18n/src/useFilter.ts#L58

Upvotes: 0

Related Questions