Skip to content

Instantly share code, notes, and snippets.

@Jaballadares
Last active June 24, 2021 16:51
Show Gist options
  • Select an option

  • Save Jaballadares/62cc0c89850769cea10545427b672c9f to your computer and use it in GitHub Desktop.

Select an option

Save Jaballadares/62cc0c89850769cea10545427b672c9f to your computer and use it in GitHub Desktop.
Official Personal Lib | JLIB
const renameKeys = (keysMap, obj) =>
Object.keys(obj).reduce(
(acc, key) => ({
...acc,
...{ [keysMap[key] || key]: obj[key]},
}), {}
)
const JSONtoCSV = (arr, columns, delimiter = ',') =>
[
columns.join(delimiter),
...arr.map(obj =>
columns.reduce(
(acc, key) =>
`${acc}${!acc.length ? '' : delimiter}"${!obj[key] ? '' : obj[key]}"`,
''
)
),
].join('\n');
const removeFalseysFromObject = val => {
const data = Array.isArray(val) ? val.filter(Boolean) : val;
return Object.keys(data).reduce(
(acc, key) => {
const value = data[key];
if (Boolean(value))
acc[key] = typeof value === 'object' ? removeFalseysFromObject(value) : value;
return acc;
},
Array.isArray(val) ? [] : {}
);
};
const objectToEntries = obj => Object.keys(obj).map(k => [k, obj[k]]);
const arrayToCSV = (arr, delimiter = ',') =>
arr
.map(v =>
v.map(x => (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x)).join(delimiter)
)
.join('\n');
const uniqueElementsBy = (arr, fn) =>
arr.reduce((acc, v) => {
if (!acc.some(x => fn(v, x))) acc.push(v);
return acc;
}, []);
// Examples
console.log(uniqueElementsBy(
[
{ id: 0, value: 'a' },
{ id: 1, value: 'b' },
{ id: 2, value: 'c' },
{ id: 1, value: 'd' },
{ id: 0, value: 'e' }
],
(a, b) => a.id == b.id
)); // [ { id: 0, value: 'a' }, { id: 1, value: 'b' }, { id: 2, value: 'c' } ]
/**
*
* @param {*} array - array to partition into pieces
* @param {*} isValid - function that filters criteria based on your need
* @returns
*/
function partition(array, isValid) {
return array.reduce(([pass, fail], elem) => {
return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]];
}, [[], []]);
}
const myArray = [1, 3, 5, 6, 7, 8, 10, 12]
const [pass, fail] = partition(myArray, (e) => e > 5);
// fail: [1, 3, 5] // pass: [6, 7, 8, 10, 12]
/**
* Merge 2 Arrays of Objects in Array by Prop
* @param {array} a
* @param {array} b
* @param {string} prop - property to merge based on
* @returns {array} merged array
*/
const combine = (a, b, prop) =>
Object.values(
[...a, ...b].reduce((acc, v) => {
if (v[prop])
acc[v[prop]] = acc[v[prop]]
? { ...acc[v[prop]], ...v }
: { ...v };
return acc;
}, {})
);
// combine([
// { id: 1, name: 'John', age: 28 },
// { id: 2, name: 'Maria' },
// { id: 3, age: 26 }
// ],[
// { id: 1, name: 'John', age: 28 },
// { id: 2, name: 'Maria' },
// { id: 3, age: 26 }
// ],"age")
// shortened query selector
const get = function(selector, scope) {
scope = scope ? scope : document;
return scope.querySelector('selector');
}
// querySelectorAll shortcut
const getAll = function(selector, scope) {
scope = scope ? scope : document;
return [].slice.call(scope.querySelectorAll(selector));
}
const insertAfterHTML = (html, elem) => elem.insertAdjacentHTML('afterend', html);
/**
* Serialize form data
* @param {object} formElement
* @return {object}
*/
const serialize = (formEle) =>
Array.from(new FormData(formEle)).reduce(
(p, [k, v]) =>
Object.assign({}, p, {
[k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v,
}),
{}
);
// Mini UI/Element Builder
let ui = {};
(function() {
ui.createRoot = function(id = 'app-root') {
const root = create(null, 'div', id);
document.insertBefore(root, document.body.firstChild);
return root;
}
ui.create = function(tag, id, className) {
return create(null, tag, id, className);
};
function create(parent, tag, id, className) {
const elem = document.createElement(tag);
if (id) elem.id = id;
if (className) elem.className = className;
if (parent) parent.appendChild(elem);
addCustomMethods(elem);
return elem;
}
function addText(text, element) {
const textNode = document.createTextNode('div');
element.appendChild(textNode);
}
function addBreak(parent) {
const br = document.createElement('br');
parent.appendChild(br);
}
function addCustomMethods(elem) {
elem.create = function(tag, id, className) {
return create(elem, tag, id, className);
};
elem.addText = functoin(text) {
addText(text, elem);
};
elem.addBreak = function() {
addBreak(elem);
};
}
ui.get = function(id) {
const elem = document.getElementById(id);
addCustomMethods(elem);
return elem;
}
})();
/**
* Pluck certain keys from array of
* Extract subset of JSON collection
*/
const users = energyTeam.map((member) => {
const { id, name, title, email, phone } = member;
return { id, name, title, email, phone };
});
// Filter an array of objects by key
/**
* Find Unique IDs in an array
*/
function filterByKey(arr, prop) {
return arr.filter((v, i, a) => a.findIndex(t => (t.prop === v.prop)) ===i);
}
const testOb = [
{
name: 'john',
age: 15
},
{
name: 'smith'
},
{
name: 'john'
}
]
console.log(filterByKey(testObj, 'name'))
/**
* Check if value is function
* @param {any}
* @returns {boolean} - whether value is function or not
*/
const isFunction = (v) =>
[
'[object Function]',
'[object GeneratorFunction]',
'[object AsyncFunction]',
'[object Promise]',
].includes(Object.prototype.toString.call(v));
// Examples
isFunction(function () {}); // true
isFunction(function* () {}); // true
isFunction(async function () {}); // true
/**
* Compose (pipe) functions from left to right
* @param {function[]} - fns - array of functions
*/
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
//Example
const lowercase = str => str.toLowerCase();
const capitalize = str => `${str.charAt(0).toUppercase()}${str.slice(1)}`;
const reverse = str => str.split('').reverse().join('');
const fn = pipe(lowercase, capitalize,reverse);
fn('Hello World') === 'dlroW olleH'; // true
/**
* Execute function once
* @param {function} fn - function to execute once
*/
const runOnce = fn => ((ran = false) => () => ran ? fn : (ran = !ran, fn =fn()))();
//Example
let n = 0;
const isOnce = runOnce(() => ++n);
isOnce(); // n = 1;
isOnce(); // n = 1
isOnce(); // n = 1
/**
* Convert string to number
* @param {string} str - string to be converted to number type
* @return {int}
*/
const toNumber = str => +str;
// Mapping API Requests
const urls = ['google.com', 'yahoo.com', 'netscape.com', 'aol.com'];
const resultingPromises = urls.map(url => makeHttpRequest(url));
const results = await Promise.all(resultingPromises);
// Mapping with Index
const urls = ['google.com', 'yahoo.com', 'netscape.com', 'aol.com'];
const resultingPromises = urls.map((url, index) => makeHttpRequest(url, index));
const results = await Promise.all(resultingPromises);
// for-each
const urls = ['google.com', 'yahoo.com', 'netscape.com', 'aol.com'];
urls.forEach((url) => {
try {
await makeHttpRequest(url);
} catch(err) {
console.error(`${err} bad practice`);
}
})
/** References can be found at: https://1loc.dev/ */
/**
* CHeck if multiple objects are equal
* @param {[]Object}
* @return {boolean}
*/
const areObjectsEqual = (...objects) =>
objects.array((obj) => JSON.stringify(obj === JSON.stringify(objects[0])));
//Example
areObjectsEqual({ foo: 'bar' }, { foo: 'bar' }); // true
areObjectsEqual({ foo: 'bar' }, { bar: 'foo' }); // false;
/**
* Extract values of a property from an array of objects
* @param {array} objs - array of objects
* @param {string} property = property to pluck
* @return {array} - array of property values you want to pluck
*/
const pluck = (objs, property) => objs.map((obj) => obj[property]);
// Example
pluck(
[
{ name: 'John', age: 29 },
{ name: 'Benny', age: 10 },
{ name: 'BB', age: 23 },
],
'name'
); // ['John', 'Benny', 'BB']
/**
* Get value at a given path
* @param {string} path - string using dot notation to path of property
* @param {Object} obj - the object to walk
* @return {any} - value at path
*/
const getValueAtPath = (path, obj) =>
path.split('.').reduce((acc, c) => acc && acc[c], obj);
// Example
getValueAtPath('a.b', { a: { b: 'Hello World' } }); // 'Hello World'
/**
* Immutably rename object keys
* @param {object} keysMap - object with keys as current key and value as key to replace the key with
* @param {object} obj - the object that will have its' keys replaced
* @return {object} - object with old keys replaced by keys in keysMap
*/
const renameKeys = (keysMap, obj) =>
Object.keys(obj).reduce((acc, key) => ({
...acc,
...{ [keysMap[key] || key]: obj[key] },
}));
// Example
const objWithBadKeys = { a: 1, b: 2, c: 3 };
const keysMap = { a: 'd', b: 'e', c: 'f' };
renameKeys(keysMap, objWithBadKeys); // {d: 1, e: 2, f: 3}
/**
* Invert keys and values of object
* @param {object} obj - object to invert keys on
* @return {object} - object with original values and original keys and keys as values
*/
const invertKeysAndVals = (obj) =>
Object.keys(obj).reduce((res, k) => Object.assign(res, { [obj[k]]: k }), {});
// or
const invertValsAndKeys = (obj) =>
Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
// example
invertKeysAndVals({ a: '1', b: '2', c: '3' }); // {1: 'a', 2: 'b', 3: 'c'}
/**
* Omit a subset of properties from an object
* @param {object} - object to omit keys from
* @param {array} - array of keys to omit
* @return {obj} - object containing alll keys not included in keys passed in
*/
const omitKeys = (obj, keys) =>
Object.keys(obj)
.filter((k) => !keys.includes(k))
.reduce((res, k) => Object.assign(res, { [k]: obj[k] }), {});
//example
omitKeys({ a: '1', b: '2', c: '3' }, ['a', 'b']); // {c: '3'}
/**
* Pick a subset of keys from object
* @param {object} - object to pick keys from
* @param {keys} - array of keys to pick from object
* @return {object} - object containing only keys indicated
*/
const pickKeys = (obj, keys) =>
Object.keys(obj)
.filter((k) => keys.includes(k))
.reduce((res, k) => Object.assign(res, { [k]: obj[k] }), {});
// Example
pickKeys({ a: '1', b: '2', c: '3' }, ['a', 'b']); // {a: '1', b: '2'}
/**
* Remove all null and undefined props from object
* @param {object} - object to remove falseys from
* @return {object} - original object with falseys removed
*/
const removeNullUndefined = (obj) =>
Object.entries(obj).reduce(
(a, [k, v]) => (v == null ? a : ((a[k] = v), a)),
{}
);
//or
const removeNullAndUndefined = (obj) =>
Object.entries(obj)
.filter(([_, v]) => v != null)
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
// or
const removeFalseysSimple = (obj) =>
Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));
// Example
removeFalseysSimple({
foo: null,
bar: undefined,
fuzz: 42,
}); // {fuzz: 42}
/**
* Sort object by properties
* @param {object} obj = object to sort
* @returns {object} - original object sorted
*/
const sortObject = (obj) =>
Object.keys(obj)
.sort()
.reduce((p, c) => ((p[c] = obj[c]), p), {});
// Example
const colors = {
white: '#ffffff',
black: '#000000',
red: '#ff0000',
green: '#008000',
blue: '#0000ff',
};
sort(
colors
); /* { black: '#000000', blue: '#0000ff', green: '#008000',red: '#ff0000', white: '#ffffff' } */
const exampleCollection = [
{
team: 'Yankees',
position: 'SS',
name: 'Jeter',
},
{
team: 'Red Sox',
position: 'SS',
name: 'Nomar',
},
{
team: 'Braves',
position: '3B',
name: 'Arenado',
},
];
/**
* Count by properties of an array of objects
* @param {Array} arr - array holding collection of Objects
* @param {String} prop - the property from each object you want to count instances of
* @return {Object} - Object with prop as key and # of times it is in collection as value
*/
const countBy = (arr, prop) =>
arr.reduce(
(prev, curr) => ((prev[curr[prop]] = ++prev[curr[prop]] || 1), prev),
{}
);
console.log(countBy(exampleCollection, 'position'));
// { 'SS': 2, '3B': 1 }
/**
* Group an array of objects by key
* @param {Array} - array containing collection of Objects
* @param {String} - String to group collection by
* @return {Object[]} - Object of arrays with param as key and orginal object as values
*/
const groupBy = (arr, key) =>
arr.reduce(
(acc, item) => ((acc[item[key]] = [...(acc[item[key]] || []), item]), acc),
{}
);
/**
* Merge 2 arrays and keep duplicates
* @param {Array} a - first array to merge
* @param {Array} b - second array to merge
* @return {Array} - array containing duplicates if any exist
*/
const mergeArraysKeepDupes = (a, b) => a.concat(b);
/**
* Merge 2 arrays and keep duplicates
* @param {Array} a - first array to merge
* @param {Array} b - second array to merge
* @return {Array} - merged array containing dupes if they exist
*/
const mergeWithDupes = (a, b) => [...a, ...b];
/**
* Merge and Dedupe same values array
* @param {Array} a - first array to merge
* @param {Array} b - second array to merge
* @return {Array} - combined deduped array
*/
const mergeAndDedupe = [...new Set([...a, ...b])];
const partition = (arr, criteria) =>
arr.reduce(
(acc, i) => (acc[criteria(i) ? 0 : 1].push(i), acc), [[], []]);
console.log(partition[1,2,3,4,5], n => n % 2);
// [ [2, 4], [1, 3, 5] ]
/**
* Cast value as an array
* @param {any} value - value to return wrapped in array
* @returns {Array}
*/
const arrayify = value => Array.isArray(value) ? value : [value];
console.log(arrayify(1)); /// [1]
console.log(arrayify([1, 2, 3])) // [1, 2, 3]
/**
* Check if path is relative
* @param {string} path - path to check
* @return {boolean}
*/
const isRelative = (path) => !/^([a-z]+:)?[\\/]/i.test(path);
// Examples
isRelative('/foo/bar/baz'); // false
isRelative('C:\\foo\\bar\\baz'); // false
isRelative('foo/bar/baz.txt'); // true
isRelative('foo.md'); // true
const isAbsoluteUrl = (url) => /^[a-z][a-z0-9+.-]*:/.test(url);
// Example
isAbsoluteUrl('https://1loc.dev'); // true
isAbsoluteUrl('https://1loc.dev/foo/bar'); // true
isAbsoluteUrl('1loc.dev'); // false
isAbsoluteUrl('//1loc.dev'); // false
/**
* Convert string to camelcase
* @param {string} str - string to convert to camelcase
* @return {string} - camelcased version of string passed in
*/
const toCamelCase = (str) =>
str.trim().replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''));
// Examples
toCamelCase('background-color'); // backgroundColor
toCamelCase('-webkit-scrollbar-thumb'); // WebkitScrollbarThumb
toCamelCase('_hello_world'); // HelloWorld
toCamelCase('hello_world'); // helloWorld
const toPascalCase = (str) =>
(str.match(/[a-zA-Z0-9]+/g) || [])
.map((w) => `${w.charAt(0).toUpperCase()}${w.slice(1)}`)
.join('');
// Examples
toPascalCase('hello world'); // 'HelloWorld'
toPascalCase('hello.world'); // 'HelloWorld'
toPascalCase('foo_bar-baz'); // FooBarBaz
/**
* Convert string to URL slug
* @param {string}
* @return {string}
*/
const slugify = (str) =>
str
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w-]+/g, '');
slugify('Chapter One: Once upon a time...'); // 'chapter-one-once-upon-a-time'
/**
* Convert camelcase to kebabcase
* @param {string}
* @return {string}
*/
const kebabToCamel = (str) => str.replace(/-./g, (m) => m.toUpperCase()[1]);
// Example
kebabToCamel('background-color'); // 'backgroundColor'
/**
* Convert Camel to Kebab case
* @param {string}
* @return {string}
*/
const camelToKebab = (str) =>
str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
// Example
camelToKebab('backgroundColor'); // 'background-color'
/**
* Convert spreasheet column to number
* @param {string} col - col letter
* @return {int} - number representation of column number
*/
const getColumnAsNumberIndex = (col) =>
col.split('').reduce((prev, next) => prev * 26 + parseInt(next, 36) - 9, 0);
// Examples
getIndex('A'); // 1
getIndex('B'); // 2
getIndex('C'); // 3
getIndex('Z'); // 26
getIndex('AA'); // 27
getIndex('AB'); // 28
getIndex('AC'); // 29
getIndex('AZ'); // 52
getIndex('AAA'); // 703
getIndex('AAB'); // 704
/**
* Get file extension from file name
* @param {string} filename - filename to get extension from
* @return {string} - fileextension
*/
const getExtension = (fileName = fileName.split('.').pop());
/**
* Get filename from URL
* @param {string} - url
* @return {string} - filename from url
*/
const fileName = (url) => url.substring(url.lastIndexOf('/') + 1);
// Example
fileName('http://domain.com/path/to/document.pdf'); // 'document.pdf'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment