I have an object from which I extract values like so if I want a list:
each gear_tag in store.GearTags
li #{gear_tag.Tag.tag_name}
Now I want to concatenate all tag_names with ', ' in between. I mean that I want the resulting string to be something like:
"tag_name_1, tag_name_2, tag_name_3, tag_name_4" if the object has 4 gear_tags.
How do I achieve this?
You can use the array .map method combined with the .join method.
var tagString = store.GearTags.map(function (gear_tag) {
return gear_tag.Tag.tag_name;
}).join(', ');
Given:
store.GearTags = [
{Tag: {tag_name: 'tag_name_1'}},
{Tag: {tag_name: 'tag_name_2'}},
{Tag: {tag_name: 'tag_name_3'}}
];
The above logic would yield:
"tag_name_1, tag_name_2, tag_name_3"
Array.map iterates over every item in an array and lets you return a new value for that position in a new array that .map returns. Then Array.join does exactly what you want, returning a concatenated string of all items in the array.
With .map we create a new array with only the tag name strings in it. Then with .join we join them all together into one big comma-separated string.
Sad that I did not figure this out earlier.
- var desc_tags = ''
each gear_tag, i in store.GearTags
- if(i == retailer.GearTags.length - 1)
- desc_tags = desc_tags + gear_tag.Tag.tag_name
- else
- desc_tags = desc_tags + gear_tag.Tag.tag_name + ", "
I was typing a "- " before the "each" statement, which was causing the code not to work.
What if you do:
- var desc_tags = tags.map(function(e) {return e.Tag.tag_name}).join(', ');
Related
I am receiving a string from another application that contains various pieces of information. The items are always in the same order, but the length of variable information can change. Each item is separated by an underscore and prefixed by a letter and colon.
Example:
A:12345678_B:5482945_C:20220911_D:20230402_E:3.94
Ideally, I want to break it down so that (in Coldfusion) I can end up with a series of variable that I would set as the values of A,B,C,D and E above.
Does anyone know any easy way to do this?
Thanks!
I think #Will is missing one small part of your requirement, which is
I can end up with a series of variable[s] that I would set as the values of A,B,C,D and E above"
To me this demonstrates more what you want to achieve:
raw = "A:12345678_B:5482945_C:20220911_D:20230402_E:3.94"
asArray = raw.listToArray("_")
asStruct = asArray.reduce((struct, kvAsString) => {
var key = kvAsString.listFirst(":")
var value = kvAsString.listRest(":")
struct[key] = value
return struct
}, {})
writeDump(asStruct)
(runnable # trycf.com: https://trycf.com/gist/e84aea475957e27b5dea2643e7c207ad/acf2021?theme=monokai)
Whilst this does not create "a series of variables" it does separate out the key from the value, and from there you can append that to whatever scope you need the variables in (eg: variables.append(asStruct))
In future please:
show us what you've already tried
give us the full intended result, don't just describe it.
Basically: always include code when you ask questions.
Gives you an array of the items. If you're handy with Regular Expressions, this could be even simpler. This is Lucee compatible. Adobe CFML didn't like the var commands outside of a function.
<cfscript>
var aNewItems = [];
var sString = "A:12345678_B:5482945_C:20220911_D:20230402_E:3.94";
var aItems = listToArray(sString, "_");
for( var sLetter in aItems){
aNewItems.append(listFirst(sLetter, ":"));
}
writeDump(aNewItems);
</cfscript>
Here's an Adobe CFML version that worked on TryCF.com:
<cfscript>
local.aNewItems = [];
local.sString = "A:12345678_B:5482945_C:20220911_D:20230402_E:3.94";
local.aItems = listToArray(local.sString, "_");
for( local.sLetter in aItems){
local.aNewItems.append(listFirst(local.sLetter, ":"));
}
writeDump(local.aNewItems);
</cfscript>
And just for fun, here is a list function answer:
<cfset TheString = 'A:12345678_B:5482945_C:20220911_D:20230402_E:3.94'>
<cfoutput>
<cfloop list = #TheString# index = "NameValue" delimiters = "_">
Variable #ListFirst(NameValue, ":")# = #ListLast(NameValue, ":")# <br>
</cfloop>
</cfoutput>
Run code here ==> https://trycf.com/gist/34321917c06643de1d3c25b611243466/acf2021?theme=monokai
I have a text with some strings that I want to replace with a variable. For example:
message = """I am a message for {user} and you have puchased the following items {items} with color {color}"""
There I want to replace {user}, {items} and {color} by a variable using the following code:
message = message_template.format(user='Ali', ID = ID1)
The problem is that in some cases I will have one item and in other cases more than 5 and I need to insert them independently. Also, color and item are part of a Dataframe.
Any idea about how could I insert a changing number of variables with .format( )?
Thanks
As for multiple items convert your list to a string using : ', '.join(items)
items = ['i1','i2','i3']
message = message_template.format(user='Ali', items = ', '.join(items), color='orange')
I have an array of quotes stored in a json file called quotes.json. I read the file and am able to pick and output a random quote using the code below, but when I try to display the number of the quote, it shows up like Quote [object Object] of 3. What am I doing wrong?
[
{"quote": "quote 1"},
{"quote": "quote 2"},
{"quote": "quote 3"}
]
let quote_num = quotes[Math.floor(Math.random() * quotes.length)];
let embed = new Discord.RichEmbed()
.setTitle("Quote")
.setColor(0x27367A)
.setFooter(`Listening for ${prefix}`, `${bot_avatar_url}`)
.setThumbnail(`${bot_avatar_url}`)
.setTimestamp()
.addField(`Quote ${quote_num} of ${quotes.length}`, `'${quote_num.quote}'`)
message.channel.send({embed});
let's analyze this code
let quote_num = quotes[Math.floor(Math.random() * quotes.length)];
Firstly you get random number from the range of your array
const index = Math.floor(Math.random() * quotes.length)
Then you get object from array of objects by index
let quote_num = quotes[index]
So to get index of your object you have to edit your addField method in this way
.addField(`Quote ${index} of ${quotes.length}`, `'${quote_num.quote}'`)
Summary:
Your quote_num contains resulted object but not it's index in array of objects.
I want to have valid query like that countries=fr,be
I tried this:
countries: Joi.string().valid(['fr','be'])
But this allows only to have countries=fr or countries=be, but not multiple comma separated values. How can I achieve this?
You can use regex like so:
var list = ['fr', 'be']; // your counrty codes
var joinedList = '(' + list.join('|') + ')'; // prepare RegExp cases
var regex = new RegExp('^' + joinedList + '(,' + joinedList + ')*$') // the thing in itself
Then:
countries: Joi.string().regex(regex).required()
It would match any country code in list, alone or in a comma-separated list. I added required() as I believe valid() implicitly makes the field required as long as you don't allow undefined value.
Current code:
row.column.each(){column ->
println column.attributes()['name']
println column.value()
}
Column is a Node that has a single attribute and a single value. I am parsing an xml to input create insert statements into access. Is there a Groovy way to create the following structured statement:
Insert INTO tablename (col1, col2, col3) VALUES (1,2,3)
I am currently storing the attribute and value to separate arrays then popping them into the correct order.
I think it can be a lot easier in groovy than the currently accepted answer. The collect and join methods are built for this kind of thing. Join automatically takes care of concatenation and also does not put the trailing comma on the string
def names = row.column.collect { it.attributes()['name'] }.join(",")
def values = row.column.collect { it.values() }.join(",")
def result = "INSERT INTO tablename($names) VALUES($values)"
You could just use two StringBuilders. Something like this, which is rough and untested:
def columns = new StringBuilder("Insert INTO tablename(")
def values = new StringBuilder("VALUES (")
row.column.each() { column ->
columns.append(column.attributes()['name'])
columns.append(", ")
values.append(column.value())
values.append(", ")
}
// chop off the trailing commas, add the closing parens
columns = columns.substring(0, columns.length() - 2)
columns.append(") ")
values = values.substring(0, values.length() - 2)
values.append(")")
columns.append(values)
def result = columns.toString()
You can find all sorts of Groovy string manipulation operators here.