Last active
August 5, 2017 10:50
-
-
Save chuck0523/52d37953d4e31d4d08b01c7b661d819b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// What is this: Util funciton which filters table data | |
// behavior: | |
// First apply multiple filters to each cells with AND_OR consideration | |
// Then AND_OR to columns as well | |
const { promisify } = require('util') | |
const request = promisify(require('request')) | |
// Can be dynamic state by Redux or something | |
const state = { | |
andOr: 'and', | |
columns: [ | |
{ | |
name: 'id', | |
andOr: 'and', | |
filters: [ | |
{ type: 'contains', text: '1' }, | |
{ type: 'contains', text: '7' }, | |
] | |
}, | |
{ | |
name: 'name', | |
andOr: 'or', | |
filters: [ | |
{ type: '', text: '' }, | |
] | |
}, | |
{ | |
name: 'email', | |
andOr: 'or', | |
filters: [ | |
{ type: 'contains', text: 'org' }, | |
{ type: 'contains', text: 'uk' }, | |
] | |
}, | |
{ | |
name: 'body', | |
andOr: 'or', | |
filters: [ | |
{ type: 'contains', text: 'ullam' }, | |
{ type: 'contains', text: 'voluptas' }, | |
{ type: 'contains', text: 'quos' }, | |
] | |
} | |
] | |
} | |
// AND or OR functions | |
const AndOr = { | |
'and': Array.prototype.every, | |
'or': Array.prototype.some, | |
} | |
const matchers = { | |
'any': () => true, // default | |
'contains': (a, b) => a.includes(b), | |
'equals': (a, b) => a === b, | |
'greater than': (a, b) => a > b, | |
'less than': (a, b) => a < b, | |
} | |
const pickMatcher = (type = 'any') => { | |
return matchers[type] | |
} | |
// State resolvers | |
// Array of andOr like ['and', 'or', 'or'] | |
const andOrsState = state.columns.map(f => f.andOr) | |
// Array of filters | |
const filtersState = state.columns.map(c => c.filters) | |
// Array of types like [ ['contains', 'equals', 'contains'], [ ... ], ... ] | |
const typesState = filtersState.map(fs => fs.map(f => f.type)) | |
// Array of texts like [ ['foo', 'bar', 'baz'], [ ... ], ... ] | |
const textsState = filtersState.map(fs => fs.map(f => f.text)) | |
// Create functions | |
const rowFilter = AndOr[state.andOr] | |
const cellFilters = andOrsState.map(andOr => AndOr[andOr]) | |
const matchersArray = typesState.map(types => types.map(pickMatcher)) | |
// AND or OR search for data | |
const callFilters = (data) => { | |
// Target: row | |
return data.filter(row => { | |
// Target: cell | |
return rowFilter.call(matchersArray, (matchers, columnIndex) => { | |
const cell = row[columnIndex] | |
const cellFilter = cellFilters[columnIndex] | |
// apply multiple matchers for cell | |
return cellFilter.call(matchers, (matcher, matcherIdex) => { | |
const text = textsState[columnIndex][matcherIdex] | |
// skip when no filter | |
if(text === '') { | |
return true | |
} | |
return matcher(cell.toString(), text) | |
}) | |
}) | |
}) | |
} | |
// Data formatter | |
const toValues = (data) => { | |
// from: { id: 1, name: 'foo' }, { id: 2, name: 'bar'} | |
// to: [ [ 1, 'foo' ], [ 2, 'bar' ] ] | |
return data.map(({ id, name, email, body }) => [ id, name, email, body ]) | |
} | |
request('https://jsonplaceholder.typicode.com/comments') | |
.then(({ body }) => body) | |
.then(JSON.parse) | |
.then(toValues) | |
.then(callFilters) | |
.then(console.log) | |
.catch(console.error) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment