Allow specifying collator options (case sensitivity etc.) for “in” expressions
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
It should be possible for an expression to test whether a string appears in an array or another string while ignoring case or diacritic distinctions, or while following the collation rules of a language other than the current language.
## Problem
#6270 added an optional third argument to expression operators such as `==` and `<` to override the default collator when comparing two strings, for example to compare the strings case-insensitively or diacritic-insensitively. #8876 implements an `in` expression operator that streamlines comparing a string against a large or indefinite number of other strings. Unfortunately, this operator takes only two arguments and doesn’t accept a collator, so the developer has to choose between comparing case-insensitively or easily comparing multiple strings.
This issue is surfacing when porting `in` to NSExpression for iOS/macOS (mapbox/mapbox-gl-native-ios#168), because NSExpression supports `[c]` and `[d]` modifiers on the `IN` operator just as on the `==` and `<` operators.
## Proposed design
The `in` expression operator should accept a collator object as an optional third argument:
```js
["in", needle: (boolean, string or number), haystack: (array or string)]: boolean
["in", needle: (boolean, string or number), haystack: (array or string), collator]: boolean
```
The same issue affects the `match` operator, but it’s less clear where a collator object would go in a `match` expression without creating ambiguity for the expression evaluator.
## Implementation notes
Here’s where the `in` comparisons currently take place:
https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/definitions/in.js#L75
Here’s how custom collators are evaluated in `==` expressions:
https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/definitions/comparison.js#L179 https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/definitions/comparison.js#L62 https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/definitions/comparison.js#L154-L156 https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/definitions/comparison.js#L38 https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/types/collator.js#L51-L53 https://github.com/mapbox/mapbox-gl-js/blob/a6e85980a1bb542485d136fc768997c4d2d68901/src/style-spec/expression/types/collator.js#L47-L48
/ref #6484 mapbox/mapbox-gl-native#11786
/cc @mapbox/gl-js @chloekraw @fabian-guerra
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/style-spec/expression/definitions/in.js at the existing in comparisons, then read the collator handling in src/style-spec/expression/definitions/comparison.js and src/style-spec/expression/types/collator.js. The work is done when in accepts an optional third collator argument and applies it to string comparisons while preserving existing two-argument behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- frontend, web-dev
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100