Last active
February 25, 2017 02:36
-
-
Save abrahamjuliot/e13d3a90cf09ed561af3b1ff48db18e4 to your computer and use it in GitHub Desktop.
filter function for js arrays and or array of objects
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
// filterBy(deepArrayOfAnything, "friend", {limitTo: 2, sortBy: "name", ignoreKey: "keywords"}) | |
(function (win, doc, undefined) { | |
const isTypeArray = (obj) => Array.isArray(obj), | |
isTypeObject = (obj) => (typeof obj === 'object'), | |
isObjectOrArray = (obj) => (isTypeObject(obj) || isTypeArray(obj)), | |
isObjectAndNotArray = (obj) => (isTypeObject(obj) && !isTypeArray(obj)), | |
isNumeric = (num) => !isNaN(num), | |
isNumberBooleanOrString = (obj) => ( | |
typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean'), | |
stringVersionHas = (str, search) => str.toString().toLowerCase().indexOf(search.toLowerCase()) > -1, | |
listOrChildListHasObject = (arr) => { | |
for (let item of arr) { | |
if (isTypeArray(item) && listOrChildListHasObject(item)) {return true;} // deep search arrays | |
else if (isTypeObject(item)) {return true;} | |
} | |
return false; | |
}, | |
filterArray = (arr, val) => arr.filter((item) => stringVersionHas(item, val)), | |
limitTo = (arr, limit) => arr.slice(0, limit), | |
by = (getValue) => (a, b) => getValue(a) > getValue(b) ? 1 : -1, | |
sortBy = (arr, val) => arr.sort(by(obj => obj[val])); | |
win.filterBy = (list, query, options = null) => { | |
// throw type error if list is not an array | |
if (!isTypeArray(list)) {throw new TypeError('first argument must be of type Array');} | |
// throw type error if qury is not an number, boolean, or string | |
else if (!isNumberBooleanOrString(query)) { | |
throw new TypeError('second argument must be of type String, Boolean, or Number'); | |
} | |
// throw type error if set options is not an object | |
else if (options !== null && !isObjectAndNotArray(options)) { | |
throw new TypeError('third argument must be of type Object'); | |
} | |
// return list if it is empty | |
else if (!list.length) {return list;} | |
// begin by converting query to string and triming it | |
else {query = query.toString().trim();} | |
// query the list and return item found if it or any child lists do not have an object | |
if (!listOrChildListHasObject(list)) {return filterArray(list, query);} | |
// Otherwise, since there are objects | |
let collection = [], // to hold item object(s) containing query | |
ignoreKeyIsOn = (options !== null && typeof options.ignoreKey === 'string'); | |
// for each parent item | |
for (let parentIndex = 0, length = list.length; parentIndex < length; parentIndex++) { | |
let parentItem = list[parentIndex], keys = []; | |
if (isNumberBooleanOrString(parentItem) && stringVersionHas(parentItem, query)) { | |
collection.push(parentItem); | |
continue; // to next parent item | |
} else { | |
keys = Object.keys(parentItem); | |
} | |
// for each child item | |
for (let i = 0, childItem = {}, len = keys.length; i < len; i++) { | |
let childItem = parentItem[keys[i]]; | |
if (isObjectAndNotArray(childItem) && filterBy([childItem], query).length) { | |
if (ignoreKeyIsOn && keys[i] == options.ignoreKey) break; | |
collection.push(parentItem); | |
break; | |
} else if (isTypeArray(childItem) && filterBy(childItem, query).length) { | |
if (ignoreKeyIsOn && keys[i] == options.ignoreKey) break; | |
collection.push(parentItem); | |
break; | |
} else if (stringVersionHas(childItem, query)) { | |
if (ignoreKeyIsOn && keys[i] == options.ignoreKey) break; | |
collection.push(parentItem); | |
break; | |
} | |
} | |
} | |
// check for options | |
if (options !== null) { | |
if (isNumeric(options.limitTo) && typeof options.sortBy === 'string') { | |
return limitTo(sortBy(collection, options.sortBy), parseInt(options.limitTo, 10)); | |
} | |
else if (isNumeric(options.limitTo)) { | |
return limitTo(collection, parseInt(options.limitTo, 10)); | |
} | |
else if (typeof options.sortBy === 'string') { | |
return sortBy(collection, options.sortBy); | |
} | |
} | |
else {return collection;} | |
}; | |
})(window, document); | |
// test at https://repl.it/EyQA/53 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment