var obj = {};
for (i = 1000; i > 0; i--) {
if (i%2 == 0) {
obj[i] = 'String';
} else {
obj[i] = [ 'Array of String', 'Array of String' ];
}
}
function ClassList(collection={}) {
const classNames = {};
const keys = Object.keys(collection);
keys.forEach((key) => {
const innerCollection = collection[key];
const collectionCheck = Object.prototype.toString.call(innerCollection);
switch (collectionCheck) {
case '[object Object]': {
const innerKeys = Object.keys(innerCollection);
if (innerKeys.length === 0) {
classNames[key] = '';
break;
}
let classList = [];
innerKeys.forEach((innerKey) => {
if (!innerCollection[innerKey] || !innerCollection[innerKey].length) {
return;
}
const innerCollectionCheck = Object.prototype.toString.call(innerCollection[innerKey]);
switch (innerCollectionCheck) {
case '[object Array]':
classList.push(innerCollection[innerKey]);
break;
case '[object String]':
classList.push(innerCollection[innerKey]);
break;
}
});
classNames[key] = classList.reduce((acc, cl) => (acc += cl + ' '), '');
break;
}
case '[object Array]':
classNames[key] = innerCollection.reduce((acc, cl) => (acc += cl + ' '), '');
break;
case '[object String]':
classNames[key] = innerCollection;
break;
}
});
return classNames;
}
ClassList( obj );
function recursor(obj, primaryKey, keys = [], classList = {}) {
for (let k in obj) {
const currentCol = obj[k];
primaryKey = keys.indexOf(k) > -1 ? k : primaryKey;
classList[primaryKey] = classList[primaryKey] || '';
switch (Object.prototype.toString.call(currentCol)) {
case '[object Object]': {
classList[primaryKey] = '';
if ( Object.keys(currentCol).length === 0 ) {
break;
}
recursor(currentCol, primaryKey, keys, classList);
break;
}
case '[object Array]':
classList[primaryKey] += currentCol.join(' ') + ' ';
break;
case '[object String]':
classList[primaryKey] += currentCol + ' ';
break;
}
}
return classList;
}
function ClassList(collection = {}) {
const keys = Object.keys(collection);
return recursor(collection, false, keys);
}
ClassList( obj );
function ClassList(collection = {}) {
const result = {};
function flatten(node, str) {
const nodeType = Object.prototype.toString.call(node);
switch (nodeType) {
case '[object String]': {
str += node + ' ';
break;
}
case '[object Array]': {
str += node.join(' ') + ' ';
break;
}
case '[object Object]': {
for (const key in node) {
str += flatten(node[key], '');
}
break;
}
}
return str;
}
for (const key in collection) {
result[key] = flatten(collection[key], '').trimEnd();
}
return result;
}
ClassList(obj);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
forEach | |
Recursive 1 | |
Recursive flatten |
Test name | Executions per second |
---|---|
forEach | 2047.9 Ops/sec |
Recursive 1 | 279.8 Ops/sec |
Recursive flatten | 1535.8 Ops/sec |
Benchmark Overview
The benchmark, ClassList test v4
, tests the performance of three different implementations of the ClassList
function in JavaScript. The benchmark evaluates how efficiently each implementation can process an array-like object and extract class names from its properties.
Test Case 1: "forEach"
This test case uses the built-in Array.prototype.forEach()
method to iterate over the object's keys and values. The implementation is straightforward, but may not be optimal for performance, especially when dealing with large objects.
Pros: Easy to understand and implement, minimal dependencies.
Cons: May perform poorly on large objects due to overhead of forEach()
method.
Alternative approach: Using a simple loop (for...in
) or Object.keys()
method could potentially outperform this implementation.
Test Case 2: "Recursive 1"
This test case uses a recursive function, recursor()
, to iterate over the object's keys and values. The recursion is used to handle nested objects.
Pros: Can effectively handle nested objects, potentially faster than iterative approaches for large objects.
Cons: Recursion can lead to stack overflow errors if not handled carefully, and may be slower due to function call overhead.
Alternative approach: Iterative approach using for...in
or Object.keys()
method could simplify the implementation and avoid recursion-related issues.
Test Case 3: "Recursive flatten"
This test case uses a recursive function, flatten()
, to iterate over the object's keys and values. The recursion is used to handle nested objects and concatenate class names.
Pros: Can effectively handle nested objects and concatenate class names efficiently.
Cons: Recursion can lead to stack overflow errors if not handled carefully, and may be slower due to function call overhead.
Alternative approach: Iterative approach using for...in
or Object.keys()
method could simplify the implementation and avoid recursion-related issues.
Benchmark Results
The benchmark results show that each test case has a different execution speed. "forEach" performs the fastest, followed by "Recursive flatten", while "Recursive 1" is slower due to potential stack overflow errors.
Overall, these benchmarks demonstrate the importance of choosing an optimal algorithm for processing array-like objects and extracting class names in JavaScript. While recursion can be beneficial in certain cases, iterative approaches are generally more efficient and safer.