I have the following ugly pattern:
// defined once
const articleComponents = {
header: "",
sections: [], // {title: string, content: string}[]
footer: ""
};
// ...
function appendSuffix(suffix)
{
if (/* target header */) {
if (!articleComponents.header.endsWith(" ")) {
articleComponents.header += " ";
}
articleComponents.header += suffix;
}
else if (/* target body */) {
if (!articleComponents.sections[articleComponents.sections.length - 1].content.endsWith(" ")) {
articleComponents.sections[articleComponents.sections.length - 1].content += " ";
}
articleComponents.sections[articleComponents.sections.length - 1].content += suffix;
}
else if (/* target footer */) {
if (!articleComponents.footer.endsWith(" ")) {
articleComponents.footer += " ";
}
articleComponents.footer += suffix;
}
}
This is obviously redundant but due to the nature of the +=
operator for strings, and strings being immutable, it’s hard to simplify this.
Goals
- Ideally, in each if-statement, the
articleComponents.xyz
/articleComponents.sections[articleComponents.sections.length - 1].content
expression should appear exactly once. articleComponents
should not be modified; I rely on its format- additional helper objects inside
appendSuffix
are okay
- additional helper objects inside
C++ Counterpart
For clarity, this is how I could write it in C++ (simplified):
void appendSuffix(string_view suffix) {
string &target = /* target header */ ? articleComponents.header
: /* target body */ ? articleComponents.back().content
: /* target footer */ ? articleComponents.footer
: throw ...;
if (target.back() != ' ') {
target += ' ';
}
target += suffix;
}
It would be great if I could have something along those lines in JS.
2
Answers
To evade redundancy and simplify the code, you can establish a helper function that accepts the target component and the suffix as parameters. This function can handle the logic of appending the suffix to the relevant component. Here’s an example of how you can refactor your code:
By passing the target component ("header", "body", or "footer") and the suffix to the addSuffix function, you eliminate the need for multiple if-else statements and repetitive code. The function retrieves the appropriate component from articleComponents, checks if it ends with a space, and appends the suffix accordingly. The modified component is then assigned back to articleComponents[target].
This approach allows you to accomplish your goals of reducing repetition and avoiding direct modifications to articleComponents.
How about this one here?