Created
January 23, 2022 19:20
-
-
Save Avi-E-Koenig/96a0064b9e443f9122acd9d5c6283543 to your computer and use it in GitHub Desktop.
some doodles
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
/** | |
* Takes a string input | |
* @param {String} str | |
* @returns {String} The first not repeated character or empty string | |
*/ | |
const firstNonRepeatingLetter = (str) => { | |
function isUnique(char) { | |
let charCount = 0; | |
for (let i = 0; i < str.length; i++) { | |
const currentChar = str[i]; | |
if (currentChar == char) charCount++; | |
if (charCount > 1) return false; | |
} | |
return true; | |
} | |
for (let i = 0; i < str.length; i++) { | |
const currentChar = str[i]; | |
if (isUnique(currentChar)) return currentChar; | |
} | |
return ''; | |
}; | |
module.exports = firstNonRepeatingLetter; | |
/***************************/ | |
/** | |
* Simple greeter function | |
* @param {String} name | |
* @returns {String} "Hello, [name]!" or "Hello there!" | |
*/ | |
const sayHello = (name) => name ? `Hello, ${name}!` : "Hello there!"; | |
module.exports = sayHello; | |
/***************************/ | |
const sortByDate = (array, dateKey) => array.sort((a, b) => new Date(a[dateKey]) - new Date(b[dateKey])); | |
/** | |
* returns the offset between the earliest date and the latest date | |
* @param {String} dateStr1 date as string | |
* @param {String} dateStr2 date as string | |
* @return {Number} offset in ms | |
*/ | |
const getTimeOffset = (dateStr1, dateStr2) => { | |
if (isNaN(Date.parse(dateStr1) || isNaN(Date.parse(dateStr2)))) return NaN; | |
const dateA = new Date(dateStr1); | |
const dateB = new Date(dateStr2); | |
return dateA > dateB ? dateA - dateB : dateB - dateA; | |
} | |
/** | |
* Determines if both transactions have too many same | |
* keys and values (4 or more) | |
* @param {TransAction} transaction1 | |
* @param {TransAction} transaction2 | |
* @return {Boolean} if the count is equal to or greater than 4 | |
*/ | |
const potentialDuplicate = (transaction1, transaction2) => { | |
if (!transaction1 || !transaction2) return false; | |
let duplicateKeyValCount = 0; | |
for (const key in transaction1) { | |
if (transaction1[key] === transaction2[key]) duplicateKeyValCount++; | |
if (duplicateKeyValCount >= 4) return true; | |
} | |
return false; | |
} | |
/** | |
* Validates pair as duplicate TransActions | |
* @param {TransAction} currTransaction | |
* @param {TransAction} nextTransaction | |
* @return {Boolean} if both transactions share 4 or more key:value pairs | |
* and timeoffset between them is less than 1 minute | |
*/ | |
const validatePairAsDuplicateTransactions = (currTransaction, nextTransaction) => { | |
const isPossibleDuplicate = potentialDuplicate(currTransaction, nextTransaction); | |
const timeOffset = getTimeOffset(currTransaction.time, nextTransaction.time) <= 60000 | |
return isPossibleDuplicate && timeOffset | |
} | |
/** | |
* Reduces transactions to array of duplicate groups (as arrays) | |
* @param {TransAction[]} transactions | |
* @return {Duplicates[TransAction[]]} array of duplicate groups (as arrays) | |
*/ | |
const findDuplicateTransactions = (transactions) => { | |
const sortedDuplicates = sortByDate(transactions, 'time'); | |
return sortedDuplicates.reduce((acc, transaction, i, self) => { | |
const currTransaction = transaction; | |
const nextTransaction = self[i + 1]; | |
console.log("🚀 ~ file: index.js ~ line 88 ~ returnsortedDuplicates.reduce ~ nextTransaction", nextTransaction) | |
const processedIds = [] | |
if (processedIds.includes(currTransaction)) { | |
return acc; | |
} | |
if (!nextTransaction) { | |
acc.push([currTransaction]); | |
processedIds.push(currTransaction.id); | |
return acc; | |
} | |
if (validatePairAsDuplicateTransactions(currTransaction, nextTransaction)) { | |
acc.push([currTransaction, nextTransaction]); | |
processedIds.push(currTransaction.id, nextTransaction.id); | |
} | |
for (let i = 0; i < acc.length; i++) { | |
const currGroup = acc[i] | |
const nextGroup = acc[i + 1]; | |
if (!nextGroup) return acc; | |
const currentGroupLastMember = currGroup[currGroup.length - 1]; | |
const nextGroupFirstMember = nextGroup[0]; | |
if (validatePairAsDuplicateTransactions(currentGroupLastMember, nextGroupFirstMember)) { | |
acc[i] = currGroup.concat(nextGroup) | |
} | |
} | |
return acc; | |
}, []) | |
} | |
module.exports = findDuplicateTransactions; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment