Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save chriskalmar/d5a6771959118765bafe19a954e4057d to your computer and use it in GitHub Desktop.
Save chriskalmar/d5a6771959118765bafe19a954e4057d to your computer and use it in GitHub Desktop.
/**
* Created at 03/17/2017
* Developed by Jorge Cuesta <jorge.s.cuesta@gmail.com>
* Developed by Jeffrey Soriano <jeffreysoriano5@gmail.com>
*/
// ### Use cases
/*
keys & data -> result
keys = keys provide on batchLoadFn
data = your backend/database response array
result = sort/filter to match with keys and return on batchLoadFn
[1,2,3] & [2,3,null] = [null,2,3]
[1,2,3] & [2,3] = [null,2,3]
[1,2,3,1] & [3,2,null] = [null,2,3,null]
[1,2,3,1] & [3,2] = [null,2,3,null]
[1,2,3,1] & [3,null,2,null] = [null,2,3,null]
*/
var keys = [],
keysNotUnique = [],
results = [],
resultsUnique = [],
resultsNotUnique = [],
keyCount = 100,
uniqueResultMap = new Array(keyCount),
iterations = 10000,
id, element, i, ordered, sort;
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// generate keys unique keys and unique results.
// use case number 1
for (i = 0; i < keyCount; i++) {
keys.push(i);
results.push({id: i});
}
// use case number 2 and 3
for (i = 0; i < keyCount; i++) {
id = getRandomInt(0, 80);
element = {id: id};
keysNotUnique.push(id);
resultsNotUnique.push(element);
if (uniqueResultMap[i]) continue;
resultsUnique.push(element);
uniqueResultMap[i] = true;
}
//order keys randomly
keys.sort(k => Math.random() - 0.5);
sort = function (keys, data, prop) {
var map = {}, order = {}, e, c, k, oIndex, results = [], i, j,id;
prop = prop ? prop : 'id';
//validations of invalid values
if (!keys || (keys instanceof Array && keys.length === 0)) return [];
if (!data || (data instanceof Array && data.length === 0)) return new Array(keys.length).map(() => (null));
//map results to object, if key repeated map to array in the order received
for (i = 0; i < data.length; i++) {
e = data[i];
id = e[prop];
c = map[id];
if (!c) {
// add value
map[id] = e;
} else if (c instanceof Array) {
// push new value
c.push(e);
} else {
// is object transform to array with both values
map[id] = [c, e];
}
}
//get values from map
for (j = 0; j < keys.length; j++) {
k = keys[j];
c = map[k];
if (!(c instanceof Array)) {
results.push(c === undefined ? null : c);
} else {
//if its an array, if no index take first, else take the next one
oIndex = order[k];
oIndex = oIndex === undefined ? 0 : oIndex++;
order[k] = oIndex;
results.push(c[oIndex]);
}
}
return results;
};
console.time('not-repeated');
for (var j = 0; j < iterations; j++) {
ordered = sort(keys, results);
if (ordered.length !== keys.length) {
throw new Error('Length of results does not match with keys provided');
}
}
console.timeEnd('not-repeated');
console.time('repeated-keys-repeated-values');
for (var j = 0; j < iterations; j++) {
ordered = sort(keysNotUnique, resultsNotUnique);
if (ordered.length !== keysNotUnique.length) {
throw new Error('Length of results does not match with keys provided');
}
}
console.timeEnd('repeated-keys-repeated-values');
console.time('repeated-keys-unique-values');
for (var j = 0; j < iterations; j++) {
ordered = sort(keysNotUnique, resultsUnique);
if (ordered.length !== keysNotUnique.length) {
throw new Error('Length of results does not match with keys provided');
}
}
console.timeEnd('repeated-keys-unique-values');
var withNulls = keysNotUnique.concat([
getRandomInt(90, 200),
getRandomInt(90, 200),
getRandomInt(90, 200)
]);
withNulls.sort(k => Math.random() - 0.5);
console.time('repeated-keys-unique-values-and-nulls');
for (var j = 0; j < iterations; j++) {
ordered = sort(withNulls, resultsUnique);
if (ordered.length !== withNulls.length) {
throw new Error('Length of results does not match with keys provided');
}
}
console.timeEnd('repeated-keys-unique-values-and-nulls');
console.time('empty-keys-with-values');
ordered = sort(null, results);
if (ordered.length > 0) {
throw new Error('Length of results should be empty because does not have keys');
}
console.timeEnd('empty-keys-with-values');
console.time('with-keys-empty-values');
ordered = sort(keys, []);
if (ordered.length !== keys.length) {
throw new Error('Length of results should be equal of keys length');
}
console.timeEnd('with-keys-empty-values');
process.exit(0);
// Own samples:
// not-repeated: 38.085ms
// repeated-keys-repeated-values: 50.883ms
// repeated-keys-unique-values: 47.761ms
// not-repeated: 37.064ms
// repeated-keys-repeated-values: 46.433ms
// repeated-keys-unique-values: 45.384ms
// not-repeated: 40.600ms
// repeated-keys-repeated-values: 47.928ms
// repeated-keys-unique-values: 44.310ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment