Update consolidateLists function to take a selector function and updated tests

pull/132/head
Beaudan 6 years ago
parent f09f0f5721
commit 714a5ab8b1

@ -4,30 +4,36 @@
(function () {
window.libloki = window.libloki || {};
function consolidateLists(lists, threshold = 1){
function consolidateLists(lists, threshold, selector = (x) => x){
if (typeof threshold !== 'number') {
throw Error('Provided threshold is not a number');
}
if (typeof selector !== 'function') {
throw Error('Provided selector is not a function');
}
// calculate list size manually since `Set`
// does not have a `length` attribute
let numLists = 0;
const occurences = {};
const values = {};
lists.forEach(list => {
numLists += 1;
list.forEach(item => {
if (!(item in occurences)) {
occurences[item] = 1;
const key = selector(item);
if (!(key in occurences)) {
occurences[key] = 1;
values[key] = item;
} else {
occurences[item] += 1;
occurences[key] += 1;
}
});
});
const scaledThreshold = numLists * threshold;
return Object.entries(occurences)
.filter(keyValue => keyValue[1] >= scaledThreshold)
.map(keyValue => keyValue[0]);
return Object.keys(occurences)
.filter(key => occurences[key] >= scaledThreshold)
.map(key => values[key]);
}
window.libloki.serviceNodes = {

@ -17,13 +17,22 @@ describe('ServiceNodes', () => {
);
});
it('should throw when provided a non-function selector', () => {
[1, 'a', 0xffffffff, { really: 'not a function' }].forEach(x => {
assert.throws(() =>
libloki.serviceNodes.consolidateLists([], 1, x),
'Provided selector is not a function'
)
});
});
it('should return an empty array when the input is an empty array', () => {
const result = libloki.serviceNodes.consolidateLists([]);
const result = libloki.serviceNodes.consolidateLists([], 1);
assert.deepEqual(result, []);
});
it('should return the input when only 1 list is provided', () => {
const result = libloki.serviceNodes.consolidateLists([['a', 'b', 'c']]);
const result = libloki.serviceNodes.consolidateLists([['a', 'b', 'c']], 1);
assert.deepEqual(result, ['a', 'b', 'c']);
});
@ -36,6 +45,25 @@ describe('ServiceNodes', () => {
assert.deepEqual(result.sort(), ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
});
it('should use the selector to identify the elements', () => {
const result = libloki.serviceNodes.consolidateLists([
[{ id: 1, val: 'a'}, { id: 2, val: 'b'}, { id: 3, val: 'c'}, { id: 8, val: 'h'}],
[{ id: 4, val: 'd'}, { id: 5, val: 'e'}, { id: 6, val: 'f'}, { id: 7, val: 'g'}],
[{ id: 7, val: 'g'}, { id: 8, val: 'h'}],
], 0, x => x.id);
const expected = [
{ id: 1, val: 'a'},
{ id: 2, val: 'b'},
{ id: 3, val: 'c'},
{ id: 4, val: 'd'},
{ id: 5, val: 'e'},
{ id: 6, val: 'f'},
{ id: 7, val: 'g'},
{ id: 8, val: 'h'},
];
assert.deepEqual(result.sort((a, b) => a.val > b.val), expected);
});
it('should return the intersection of all lists when threshold is 1', () => {
const result = libloki.serviceNodes.consolidateLists([
['a', 'b', 'c', 'd'],

Loading…
Cancel
Save