feat(ott-91): own filtering and sorting function

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
mirlan.maksitaliev 6 years ago
parent 09568e1b65
commit 5a89830556
  1. 69
      src/features/CountrySelector/helpers/__tests__/index.tsx
  2. 77
      src/features/CountrySelector/helpers/index.tsx

@ -0,0 +1,69 @@
import { matchSort } from '..'
it('does not sort items when query is empty', () => {
const items = [
{ name: 'app' },
{ name: 'apple' },
]
const query = ''
const result = matchSort(
items,
'name',
query,
)
expect(result).toEqual(items)
})
it('non matching words omitted', () => {
const items = [
{ name: 'banana' },
{ name: 'app' },
{ name: 'apple' },
]
const query = 'app'
const result = matchSort(
items,
'name',
query,
)
expect(result).toEqual([
items[1],
items[2],
])
})
it('matching words go first', () => {
const items = [
{ name: 'apple' },
{ name: 'app' },
]
const query = 'app'
const result = matchSort(
items,
'name',
query,
)
expect(result).toEqual([
items[1],
items[0],
])
})
it('words starting with query word go second', () => {
const items = [
{ name: 'apple' },
{ name: 'app' },
{ name: 'buggy app' },
]
const query = 'app'
const result = matchSort(
items,
'name',
query,
)
expect(result).toEqual([
items[1],
items[0],
items[2],
])
})

@ -0,0 +1,77 @@
import startsWith from 'lodash/startsWith'
import orderBy from 'lodash/orderBy'
import toLower from 'lodash/toLower'
import filter from 'lodash/filter'
import split from 'lodash/split'
import size from 'lodash/size'
import some from 'lodash/some'
type Item = { [key: string]: any }
type Func = <T extends Item, K extends keyof T>(
items: Array<T>,
key: K,
query: string,
) => Array<T>
const startsWithIgnore = (word: string, target: string) => (
startsWith(toLower(word), toLower(target))
)
const hasManyWords = (word: string) => size(split(word, ' ')) > 1
const atLeastOneWordStartsWith = (word: string, target: string) => {
const words = split(word, ' ')
return some(words, (w) => startsWithIgnore(w, target))
}
const filterMatching: Func = (
items,
key,
query,
) => (
filter(items, (item) => {
const value = item[key]
if (startsWithIgnore(value, query)) return true
if (hasManyWords(value)) return atLeastOneWordStartsWith(value, query)
return false
})
)
const sortMatching: Func = (
items,
key,
query,
) => (
orderBy(
items,
(item) => {
if (item[key] === query) return 10
if (startsWithIgnore(item[key], query)) {
return 5
}
return 0
},
'desc',
)
)
export const matchSort: Func = (
items,
key,
query,
) => {
if (!query) return items
const filteredItems = filterMatching(
items,
key,
query,
)
return sortMatching(
filteredItems,
key,
query,
)
}
Loading…
Cancel
Save