mapbox / mapbox/mapbox-gl-js

Allow specifying collator options (case sensitivity etc.) for “in” expressions

Open
#9,339 0 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature :green_apple: needs discussion :speech_balloon:
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.