Implemented functions `nextSearchResult` and `previousSearchResult`
This commit is contained in:
parent
100efb35ae
commit
6ba53f7364
|
@ -542,6 +542,54 @@ export function search (data, text): SearchResult[] {
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the next search result given a current search result
|
||||||
|
* - When the current search result is the last one, the search will wrap around
|
||||||
|
* and return the first result as next.
|
||||||
|
* - When current search result is not found, the first search result will be
|
||||||
|
* returned as next
|
||||||
|
* - When `searchResults` is empty, null will be returned
|
||||||
|
*/
|
||||||
|
export function nextSearchResult (searchResults: SearchResult[], current: SearchResult): SearchResult | null {
|
||||||
|
if (searchResults.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = searchResults.findIndex(searchResult => isEqual(searchResult, current))
|
||||||
|
if (index !== -1) {
|
||||||
|
return index < searchResults.length - 1
|
||||||
|
? searchResults[index + 1]
|
||||||
|
: searchResults[0]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return searchResults[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the previous search result given a current search result
|
||||||
|
* - When the current search result is the first one, the search will wrap around
|
||||||
|
* and return the last result as next.
|
||||||
|
* - When current search result is not found, the last search result will be
|
||||||
|
* returned as next
|
||||||
|
* - When `searchResults` is empty, null will be returned
|
||||||
|
*/
|
||||||
|
export function previousSearchResult (searchResults: SearchResult[], current: SearchResult): SearchResult | null {
|
||||||
|
if (searchResults.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = searchResults.findIndex(searchResult => isEqual(searchResult, current))
|
||||||
|
if (index !== -1) {
|
||||||
|
return index > 0
|
||||||
|
? searchResults[index - 1]
|
||||||
|
: last(searchResults)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return searchResults[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge searchResults into the data
|
* Merge searchResults into the data
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@ import test from 'ava';
|
||||||
import {
|
import {
|
||||||
jsonToData, dataToJson, patchData, pathExists, transform, traverse,
|
jsonToData, dataToJson, patchData, pathExists, transform, traverse,
|
||||||
parseJSONPointer, compileJSONPointer,
|
parseJSONPointer, compileJSONPointer,
|
||||||
expand, addErrors, search, addSearchResults
|
expand, addErrors, search, addSearchResults, nextSearchResult, previousSearchResult
|
||||||
} from '../src/jsonData'
|
} from '../src/jsonData'
|
||||||
|
|
||||||
|
|
||||||
|
@ -939,3 +939,59 @@ test('search', t => {
|
||||||
|
|
||||||
t.deepEqual(updatedData, JSON_DATA_EXAMPLE_SEARCH_L)
|
t.deepEqual(updatedData, JSON_DATA_EXAMPLE_SEARCH_L)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('nextSearchResult', t => {
|
||||||
|
const searchResults = [
|
||||||
|
{dataPath: ['obj', 'arr', '2', 'last'], type: 'property'},
|
||||||
|
{dataPath: ['str'], type: 'value'},
|
||||||
|
{dataPath: ['nill'], type: 'property'},
|
||||||
|
{dataPath: ['nill'], type: 'value'},
|
||||||
|
{dataPath: ['bool'], type: 'property'},
|
||||||
|
{dataPath: ['bool'], type: 'value'}
|
||||||
|
]
|
||||||
|
|
||||||
|
t.deepEqual(nextSearchResult(searchResults,
|
||||||
|
{dataPath: ['nill'], type: 'property'}),
|
||||||
|
{dataPath: ['nill'], type: 'value'})
|
||||||
|
|
||||||
|
// wrap around
|
||||||
|
t.deepEqual(nextSearchResult(searchResults,
|
||||||
|
{dataPath: ['bool'], type: 'value'}),
|
||||||
|
{dataPath: ['obj', 'arr', '2', 'last'], type: 'property'})
|
||||||
|
|
||||||
|
// return first when current is not found
|
||||||
|
t.deepEqual(nextSearchResult(searchResults,
|
||||||
|
{dataPath: ['non', 'existing'], type: 'value'}),
|
||||||
|
{dataPath: ['obj', 'arr', '2', 'last'], type: 'property'})
|
||||||
|
|
||||||
|
// return null when searchResults are empty
|
||||||
|
t.deepEqual(nextSearchResult([], {dataPath: ['non', 'existing'], type: 'value'}), null)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('previousSearchResult', t => {
|
||||||
|
const searchResults = [
|
||||||
|
{dataPath: ['obj', 'arr', '2', 'last'], type: 'property'},
|
||||||
|
{dataPath: ['str'], type: 'value'},
|
||||||
|
{dataPath: ['nill'], type: 'property'},
|
||||||
|
{dataPath: ['nill'], type: 'value'},
|
||||||
|
{dataPath: ['bool'], type: 'property'},
|
||||||
|
{dataPath: ['bool'], type: 'value'}
|
||||||
|
]
|
||||||
|
|
||||||
|
t.deepEqual(previousSearchResult(searchResults,
|
||||||
|
{dataPath: ['nill'], type: 'property'}),
|
||||||
|
{dataPath: ['str'], type: 'value'})
|
||||||
|
|
||||||
|
// wrap around
|
||||||
|
t.deepEqual(previousSearchResult(searchResults,
|
||||||
|
{dataPath: ['obj', 'arr', '2', 'last'], type: 'property'}),
|
||||||
|
{dataPath: ['bool'], type: 'value'})
|
||||||
|
|
||||||
|
// return first when current is not found
|
||||||
|
t.deepEqual(previousSearchResult(searchResults,
|
||||||
|
{dataPath: ['non', 'existing'], type: 'value'}),
|
||||||
|
{dataPath: ['obj', 'arr', '2', 'last'], type: 'property'})
|
||||||
|
|
||||||
|
// return null when searchResults are empty
|
||||||
|
t.deepEqual(previousSearchResult([], {dataPath: ['non', 'existing'], type: 'value'}), null)
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue