SOLVED

Re: A basic foreach issue

Go to solution
Jo_Pitts1
Level 10 - Community Advisor

A basic foreach issue

Basic as in simple.. not as in BASIC (sorry - old person language joke)

I have this simple piece of code

 

#set ($seminarList = "A;1|B;5|C;3")
#foreach ($myitem in $seminarList.split("[|]"))
  ${myitem}
  #end

 

And it is spitting the dummy (completely refusing to do anything useful).

I was expecting it to spit out A;1 B;5 C;3 (obviously, no styling on this yet, but that's not the current issue)

What am I managing to miss here? 

1 ACCEPTED SOLUTION

Accepted Solutions
SanfordWhiteman
Level 10 - Community Moderator

Re: A basic foreach issue

#set( $allSeminarDetails = [ 
  {"CODE":"GNG","BLURB":"Come to GNG and learn about Poodles"},
  {"CODE":"POY","BLURB":"It's POYsonal Now"},
  {"CODE":"GUL","BLURB":"GULivers travels have nothing on life here"},
  {"CODE":"WTG","BLURB":"Waiting Waiting Waiting"}
] )  
#set( $currentSeminarList = $lead.metlifecompetitiondatas2 )
#set( $currentSeminarCodes = $currentSeminarList.split("[|]") )
## this list will hold matched seminars
#set( $currentSeminarDetails = [] )
## find matching seminar in master list
#foreach( $code in $currentSeminarCodes )
#foreach( $detail in $allSeminarDetails )
#if( $detail.CODE.equals($code) )
#set( $void = $currentSeminarDetails.add($detail) )
#break
#end
#end
#end
## iterate over matches only
#foreach( $seminar in $currentSeminarDetails )
${seminar}
#end

View solution in original post

16 REPLIES 16
SanfordWhiteman
Level 10 - Community Moderator

Re: A basic foreach issue

That's the correct syntax to split on the pipe character (which is escaped by being in the character class []).

 

I assume you have this in a Velocity {{my.token}} in an email, yes?

Jo_Pitts1
Level 10 - Community Advisor

Re: A basic foreach issue

@SanfordWhiteman yes - this is in a token.  

I've tweaked things and made it behave, so now my next challenge.

How to take my split string, and find each matching value in an array.

I've got to this point:

 

#set( $seminarDetails = [ 
  {"CODE":"GNG","BLURB":"Come to GNG and learn about Poodles"},
  {"CODE":"POY","BLURB":"It's POYsonal Now"},
  {"CODE":"GUL","BLURB":"GULivers travels have nothing on life here"},
  {"CODE":"WTG","BLURB":"Waiting Waiting Waiting"}
  ])
  
#set ($seminarList = ${lead.metlifecompetitiondatas2})
#set ($seminarArray = $seminarList.split("[|]"))
#foreach ($seminarCode in $seminarArray)
  ## how to find the SeminarCode in the SeminarDetails array.
  #end

 

 

Let's assume the passed in field {lead.metlifecompetitiondatas2} contains POY|GUL.

My foreach loop will iterate twice (happy day).  What I want to do is get access to the appropriate blurb in the array at the top for output in the email (without doing some silly nested foreach loop on the seminarDetails array).

And I am sure I could condense some of this (i.e. splitting the marketo field straight into an array), but I like to keep it nice and stepwise so I can understand each bit before condensing once I have a handle on what is going on.

SanfordWhiteman
Level 10 - Community Moderator

Re: A basic foreach issue

#set( $allSeminarDetails = [ 
  {"CODE":"GNG","BLURB":"Come to GNG and learn about Poodles"},
  {"CODE":"POY","BLURB":"It's POYsonal Now"},
  {"CODE":"GUL","BLURB":"GULivers travels have nothing on life here"},
  {"CODE":"WTG","BLURB":"Waiting Waiting Waiting"}
] )  
#set( $currentSeminarList = $lead.metlifecompetitiondatas2 )
#set( $currentSeminarCodes = $currentSeminarList.split("[|]") )
## this list will hold matched seminars
#set( $currentSeminarDetails = [] )
## find matching seminar in master list
#foreach( $code in $currentSeminarCodes )
#foreach( $detail in $allSeminarDetails )
#if( $detail.CODE.equals($code) )
#set( $void = $currentSeminarDetails.add($detail) )
#break
#end
#end
#end
## iterate over matches only
#foreach( $seminar in $currentSeminarDetails )
${seminar}
#end
Jo_Pitts1
Level 10 - Community Advisor

Re: A basic foreach issue

So a nested loop in other words :).... Darn it I was hoping for something more elegant!  Thanks for the help @SanfordWhiteman 

Next silly question.  in this line here:

#set( $void = $currentSeminarDetails.add($detail) )

How can I add one extra element that is NOT in the $allSeminarDetails array.  In this instance, I also know the number of attendees (which can vary by seminar).

 

So in essence what I want (and will experiment with shortly) is something like

#set( $void = $currentSeminarDetails.add($detail,$attendees) )

but I feel like that won't work

 

SanfordWhiteman
Level 10 - Community Moderator

Re: A basic foreach issue

If you used String keys in the Map it would be much shorter, fwiw:

#set( $allSeminarDetails = {
  "GNG" : {
    "BLURB":"Come to GNG and learn about Poodles"
  },
  "POY" : {
    "BLURB":"It's POYsonal Now"
  },
  "GUL" : {
    "BLURB" : "GULivers travels have nothing on life here"
  },
  "WTG" : {
    "BLURB" : "Waiting Waiting Waiting"
  }
} )  
#set( $currentSeminarList = $lead.metlifecompetitiondatas2 )
#set( $currentSeminarCodes = $currentSeminarList.split("[|]") )
## this list will hold matched seminars
#set( $currentSeminarDetails = [] )
## find matching seminar in master list
#foreach( $code in $currentSeminarCodes )
#set( $void = $currentSeminarDetails.add($allSeminarDetails[$code]) )
#end
## iterate over matches only
#foreach( $seminar in $currentSeminarDetails )
${seminar}
#end
Jo_Pitts1
Level 10 - Community Advisor

Re: A basic foreach issue

@SanfordWhiteman ,

I can switch to string keys quite happily and easily 🙂

I'm always happy to find nicer/better ways of doing things especially as it avoids the ghastly nested loop.

How far off the mark am I in my desire to add more than just the details from allSeminarDetails (i.e. + the number of attendees) in my previous message.

SanfordWhiteman
Level 10 - Community Moderator

Re: A basic foreach issue


I'm always happy to find nicer/better ways of doing things especially as it avoids the ghastly nested loop.

It's not always better, as there may be reasons where having a string key isn't flexible enough. But for this case it'd be better.

 

What do you mean by "and number of attendees"?

Jo_Pitts1
Level 10 - Community Advisor

Re: A basic foreach issue

@SanfordWhiteman 

So, in my string, I actually get something like:

GNG;4|POY;3

 

The code gives me the seminar, and the number is the attendees.

Ultimately, my allSeminarDetails map will have blurb, date, time, and a URL.

My currentSeminarDetails will end up with the right rows from allSeminarDetails PLUS the attendees for that seminar.

That way I can emit it all in the HTML of the email.

Sorry for not making this all clear at the beginning - I was trying to give a simplified example and build it up from there.

Jo_Pitts1
Level 10 - Community Advisor

Re: A basic foreach issue

@SanfordWhiteman  (and for the general amusement and hopefully edification of others),

I've made solid progress.  My code is working as expected, and I'm getting to grips with the string maps stuff quite nicely.

The output section at the end is almost 'debug' at the moment, but will go into a nice table shortly.

 

#set( $allSeminarDetails = {
  "GNG" : {
    "blurb":"Come to GNG and learn about Poodles",
    "date":"5 Aug 2020",
    "attendees":0
  },
  "POY" : {
    "blurb":"It's POYsonal Now",
    "date":"6 Aug 2020",
    "attendees":0
  },
  "GUL" : {
    "blurb" : "GULivers travels have nothing on life here",
    "date":"7 Aug 2020",
    "attendees":0
  },
  "WTG" : {
    "blurb" : "Waiting Waiting Waiting",
    "date":"8 Aug 2020",
    "attendees":0
  },
  "POH" : {
    "blurb" : "POH POH POH your boat",
    "date":"9 Aug 2020",
    "attendees":0
  }
} )  
#set( $currentSeminarList = $lead.metlifecompetitiondatas2 )
#set( $currentSeminarCodes = $currentSeminarList.split("[|]") )
## this list will hold matched seminars
#set( $currentSeminarDetails = [] )
## find matching seminar in master list
#foreach( $code in $currentSeminarCodes )
  #set( $currentRegistration = $code.split("[;]") )
  #set( $villageCode = $currentRegistration[0] )
  #set( $attendees = $currentRegistration[1] )
  #set( $aSeminar = $allSeminarDetails[$villageCode]) 
  #set( $aSeminar.attendees = $currentRegistration[1] )
  #set( $void = $currentSeminarDetails.add( $aSeminar ) )
  #end
## iterate over matches only
#foreach( $seminar in $currentSeminarDetails )
  ${seminar.blurb}  
  ${seminar.date}  
  ${seminar.attendees}<BR><BR>
  #end

 

What I'm most curious about is where can I improve what I'm doing.  Are their areas of inelegance or inefficiency in here that I could be doing better?

 

Cheers

Jo