add createFilter filter util method

pull/67/head
dperolio 3 years ago
parent 10315f7bc7
commit 64d7862397
No known key found for this signature in database
GPG Key ID: 3E9BBAA710D3DDCE

@ -0,0 +1,108 @@
import Fuse from 'fuse.js';
import { flattenArray } from './Array';
export const createFilter = (term, keys, options = {}) => {
function getValuesForKey (key, item) {
const keys = key.split('.');
let results = [ item ];
keys.forEach(_key => {
const tmp = [];
results.forEach(result => {
if (result) {
if (result instanceof Array) {
const index = parseInt(_key);
if (!isNaN(index)) {
return tmp.push(result[index]);
}
result.forEach(res => {
tmp.push(res[_key]);
});
} else if (result && typeof result.get === 'function') {
tmp.push(result.get(_key));
} else {
tmp.push(result[_key]);
}
}
});
results = tmp;
});
// Support arrays and Immutable lists.
results = results.map(r => (r && r.push && r.toArray) ? r.toArray() : r);
results = flattenArray(results);
return results.filter(r => typeof r === 'string' || typeof r === 'number');
}
function searchStrings (strings, term, { caseSensitive, fuzzy, sortResults, exactMatch } = {}) {
strings = strings.map(e => e.toString());
try {
if (fuzzy) {
if (typeof strings.toJS === 'function') {
strings = strings.toJS();
}
const fuse = new Fuse(
strings.map(s => { return { id: s }; }),
{ keys: [ 'id' ], id: 'id', caseSensitive, shouldSort: sortResults }
);
return fuse.search(term).length;
}
return strings.some(value => {
try {
if (!caseSensitive) {
value = value.toLowerCase();
}
if (exactMatch) {
term = new RegExp(`^${term}$`, 'i');
}
if (value && value.search(term) !== -1) {
return true;
}
return false;
} catch (e) {
return false;
}
});
} catch (e) {
return false;
}
}
return (item) => {
if (term === '') { return true; }
if (!options.caseSensitive) {
term = term.toLowerCase();
}
const terms = term.split(' ');
if (!keys) {
return terms.every(term => searchStrings([ item ], term, options));
}
if (typeof keys === 'string') {
keys = [ keys ]
}
return terms.every(term => {
// allow search in specific fields with the syntax `field:search`
let currentKeys;
if (term.indexOf(':') !== -1) {
const searchedField = term.split(':')[0];
term = term.split(':')[1];
currentKeys = keys.filter(key => key.toLowerCase().indexOf(searchedField) > -1);
} else {
currentKeys = keys;
}
return currentKeys.some(key => {
const values = getValuesForKey(key, item);
return searchStrings(values, term, options);
});
});
};
};
Loading…
Cancel
Save