Last active
July 30, 2021 16:56
-
-
Save petsel/86d7ce468512fffdb051bf9e650d1e4f to your computer and use it in GitHub Desktop.
This file contains 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
const | |
arrPrototype = Object.getPrototypeOf([]); | |
const { | |
from: arrayFrom, | |
isArray, | |
} = Array; | |
function isFunction(type) { | |
return ( | |
(typeof type === 'function') | |
&& (typeof type.call === 'function') | |
&& (typeof type.apply === 'function') | |
); | |
} | |
function getSanitizedTarget(type) { | |
return (type ?? null); | |
} | |
function getNotationGroup(notation) { | |
// - inspired by `:nth-child()` CSS pseudo-class ... [https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child] | |
// | |
// - an array's `nth-item` notation ... [https://regex101.com/r/tZmeZS/1/] | |
// | |
const regXNthItemNotation = (/^(?<nthBase>[+-]?\d+)(?:\*?(?<series>n)(?<crementer>[+-]\d+)?)?$/); | |
const regXSanitizeNotation = (/\s+/g); | |
return String(notation) | |
.replace(regXSanitizeNotation, '') | |
.match(regXNthItemNotation) | |
?.groups; | |
} | |
function getNthIndexSeriesDescending(getNthIndex, maximumIndex) { | |
const nthIndexList = []; | |
let nthIndex; | |
let n = -1; | |
while ((nthIndex = getNthIndex(++n)) >= 0) { | |
if (nthIndex <= maximumIndex) { | |
nthIndexList.push(nthIndex); | |
} | |
} | |
return nthIndexList; | |
} | |
function getNthIndexSeriesAscending(getNthIndex, maximumIndex) { | |
const nthIndexList = []; | |
let nthIndex; | |
let n = -1; | |
while ((nthIndex = getNthIndex(++n)) <= maximumIndex) { | |
if (nthIndex >= 0) { | |
nthIndexList.push(nthIndex); | |
} | |
} | |
return nthIndexList; | |
} | |
function getNthIndexSeriesList(notationGroup, maximumIndex) { | |
const nthIndexList = []; | |
let { series, nthBase, crementer } = notationGroup; | |
nthBase = Number(nthBase); | |
crementer = Number(crementer ?? 0); | |
const getNthIndex = n => ((nthBase * n) + crementer); | |
if (!!series) { | |
if (nthBase !== 0) { | |
const isDescending = (getNthIndex(0) > getNthIndex(1)); | |
nthIndexList.push( | |
...isDescending | |
? getNthIndexSeriesDescending(getNthIndex, maximumIndex) | |
: getNthIndexSeriesAscending(getNthIndex, maximumIndex) | |
); | |
} else if (crementer >= 0) { | |
// `crementer` in this case equals the result of the first nth-index computation. | |
nthIndexList.push(crementer); | |
} | |
} else if ((nthBase >= 0) && (nthBase <= maximumIndex)) { | |
// just the `nthBase` as the sole nth-index item. | |
nthIndexList.push(nthBase); | |
} | |
return nthIndexList; | |
} | |
function nthItem(notation, callback, target) { | |
let result = []; | |
const notationGroup = getNotationGroup(notation); | |
const arr = notationGroup && ((isArray(this) && this) || arrayFrom(this ?? [])); | |
// fail silently. | |
const nthIndexList = arr && isFunction(callback) && getNthIndexSeriesList(notationGroup, (arr.length - 1)); | |
if (nthIndexList && nthIndexList.length) { | |
target = getSanitizedTarget(target); | |
result = nthIndexList.map(nthIndex => | |
callback.call(target, arr[nthIndex], nthIndex, arr) | |
); | |
} | |
return result; | |
} | |
Object.defineProperty(arrPrototype, 'nthItem', { | |
configurable: true, | |
writable: true, | |
value: nthItem | |
}); | |
Object.defineProperty(arrPrototype.nthItem, 'toString', { | |
value: () => 'function nthItem() { [custom code] }' | |
}); | |
// export default Array; | |
/** | |
* Get every nth element of an array | |
* [https://stackoverflow.com/questions/68588326/get-every-nth-element-of-an-array/68593956#68593956] | |
*/ | |
/* const cells = [ | |
'texta1', 'texta2', 'texta3', 'texta4', 'texta5', 'texta6', 'buttona', | |
'textb1', 'textb2', 'textb3', 'textb4', 'textb5', 'textb6', 'buttonb', | |
'textc1', 'textc2', 'textc3', 'textc4', 'textc5', 'textc6', 'buttonc', | |
]; | |
function processItem(nthItem, nthIndex, array) { | |
console.log({ nthItem, nthIndex }); | |
// - any passed argument can be processed. | |
// - this callback is aware of it's `this` context. | |
// - the callback's return value will be mapped to the | |
// `nthItem`'s internal array of to be processed indices | |
// which also, entirely mapped, is the `nthItem`'s return value. | |
return nthItem; | |
} | |
console.log( | |
"cells.nthItem('7n-1', processItem) ...", | |
cells.nthItem('7n-1', processItem) | |
); | |
console.log( | |
"cells.nthItem('7n-5', processItem) ...", | |
cells.nthItem('7n-5', processItem) | |
); */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment