I'm trying to loop through an array, add "
before, ",
after each member but ommit the ,
at the very last member in order to generate a JSON string:
const generate_list_data_attribute = (attribute_name, from_array) => {
let string = '';
from_array.forEach((element, key, array) => {
if(Object.is(array.length - 1, key)) {
string += `"${element}"`
} else {
string += `"${element}",`
}
});
return `data-${attribute_name}="[${string}]"`;
}
I don't like the fact that I need to Object.is(array.length-1, key)
in order to dictate what the code should do with the last member. It should be automatically handled.
To note: I understand that I can just return
to skip the usage of else
but I'm looking for a way to automatize that "last member" check more or less.
Input (array): my_array = ["food", "gourmet", "foodie"]
Operation: generate_list_data_attribute('random', my_array);
Output (string): data-random="["food", "gourmet", "foodie"]"
2 Answers 2
Use JavaScript's array methods to your advantage and solve you problem the functional way:
const generate_list_data_attribute = (attribute_name, from_array) => {
const string = from_array.map(element => `"${element}"`).join(",")
return `data-${attribute_name}="[${string}]"`
}
-
1\$\begingroup\$ You should also avoid using snake_case variable names and parameters. This is more pythonic than usual. \$\endgroup\$Fanis Despoudis– Fanis Despoudis2019年09月04日 09:37:25 +00:00Commented Sep 4, 2019 at 9:37
-
\$\begingroup\$ Got it. I'm currently churning as much knowledge about the inner works of JS as I can and it's hard to grasp all these small, but, frankly, very beautiful ways of writing code. I think that camelCase is more of an ES6 thing, right? \$\endgroup\$coolpasta– coolpasta2019年09月05日 00:31:21 +00:00Commented Sep 5, 2019 at 0:31
The JS convention is to use camelCase to name variables (All versions of JS).
generate_list_data_attribute
becomesgenerateListDataAttribute
You don't need to use Object.is in this example.
if (Object.is(array.length - 1, key)) {
is the same asif (key === array.length -1) {
Arrays contain items, arrays reference items via an index, objects reference properties via a key, and the property contains a value. Thus using more appropriate names would change
from_array.forEach((element, key, array)
tofromArray.forEach((item, index, array)
orfromArray.forEach((item, i, array)
You have access to
from_array
within theforEach
iterator and thus not need to use the 3rd argument offorEach
Rewrite
Your code is unnecessarily complex and can be done as in the example below. There are two versions as I am unsure if you intend to call the function with an empty array. The last example uses for loop, and is an alternative that avoids the need to test for the last element.
The example you gave does not match the results you want. The space is missing after the commas. The examples add the space.
Example A
This assumes that the array contains items and will return data-name="[""]"
for empty arrays which is not the same return as your function.
const arrayToNamedAttribute = (name, arr) => `data-${name}="["${arr.join('", "')}"]"`;
Example B
This example check for an empty array using a ternary arr.length ?
"${arr.join('", "')": ""
const namedAttr = (name, arr) => `data-${name}="[${arr.length ? `"${arr.join('", "')}"` : ""}]"`;
Or as
const arrayToNamedAttribute = (name, arr) => {
const arrStr = arr.length ? `"${arr.join('", "')}"` : "";
return `data-${name}="[${arrStr}]"`;
}
or replacing he {
and }
and using comma to separate expressions avoids the need to use return, and reuses the arr
argument to hold the string
const arrayToNamedAttribute = (name, arr) => (
arr = arr.length ? `"${arr.join('", "')}"` : "", `data-${name}="[${arr}]"`
);
Example C
This uses the variable join
to add the comma and space to the string
const arrayToNamedAttribute = (name, arr) => {
var arrStr = "", join = "";
for (const item of arr) {
arrStr += join + `"${item}"`;
join = ", ";
}
return `data-${name}="[${arrStr}]"`;
}
JSON.stringify(["food", "gourmet", "foodie"]); // ["food", "gourmet", "foodie]
. Works as long as the array / object does not contain circular references. \$\endgroup\$data-example="["test"]"
Right:data-example="["test"]"
\$\endgroup\$