Performance.
map
and flatMap
create copies of the arrays.
- For each new item added to the result you rebuild the whole results object
({ ...ac, [a]: null})
- For each property in the result you create a temp object to hold the key value pair.
These CPU, memory allocation, and GC burdens that can be avoided.
Some will argue that the overhead for small data sets is trivial and thus inconsequential.
Performance always matters and coding without though of performances leads to poor design habits that will bite. Many small inconsequential performance extras can quickly sum up to overall poor performance. Especially true in JavaScript where the target platform's capabilities vary so greatly. What is inconsequential on a top end desktop can be unusable on a $15 tablet.
Design
If you have followed the Code Review posting rules and your code is production code then it is very poor quality, as it is flat, in the global scope, and not reusable at all.
You should always write code inside a function. Even if its just an example writing functions will result in better design.
Style
- The indenting is poor and obscuring the logic.
- You have redundant code. Unneeded brackets
()
in headersMap
.
- Poor naming of the
_.reduce
callbacks arguments
Rewrite
Using your algorithm and rewriting into a named function your code is more readable, reusable, and cleaner (name space wise) as
function namedEvents(eventList) {
const map = ({onClick, children}) => onClick ? {onClick} : _.map(children, map);
const reduce = (result, child) => ({...result, [child]: null});
return _.reduce(
_.map(_.flatMap(eventList, map), 'onClick'),
reduce,
{}
);
}
Avoiding the needless re-creation of results for each entry you get
function namedEvents(eventList) {
const map = ({onClick, children}) => onClick ? {onClick} : _.map(children, map);
const reduce = (result, child) => (result[child] = null, result);
return _.reduce(
_.map(_.flatMap(eventList, map), 'onClick'),
reduce,
{}
);
}
Redesign
To avoid the CPU overhead the code can be written as a simple recursive function. The functions below are an order of magnitude quicker than your algorithm.
There is no need to load lodDash.js thus improving the page load time.
As you already use recursion I will assume that there are no cyclic references in the dataset.
Your code ignores children if onClick
is truthy so will do the same
For the best re-usability the key "onClick"
name can be passed as an argument.
function namedEvents(eventList, results = {}, key = "onClick") {
for (const child of eventList) {
if (child[key]) { results[child[key]] = null }
else if (child.children) { namedEvents(child.children, results, key) }
}
return results;
}
or
function namedEvents(eventList, results = {}, key = "onClick") {
for (const child of eventList) {
if (child[key]) {
results[child[key]] = null;
} else if (child.children) {
namedEvents(child.children, results, key);
}
}
return results;
}
Or not having an adaptive key
name
function namedEvents(eventList, results = {}) {
for (const {onClick, children} of eventList) {
if (onClick) { results[onClick] = null }
else if (children) { namedEvents(children, results) }
}
return results;
}
Or
function namedEvents(eventList, results = {}) {
return eventList.reduce((result, {onClick, children}) =>
onClick? (results[onClick] = null, results) :
children ? namedEvents(children, results) : results,
results
);
}