last value of sublist in freemarker - freemarker

I have a long date list with corresponding price values.
out of this list I need the last price of every month.
I sliced the list and tried to get the last value but cant!
please help.
here is part of the list:
here is my code:
<#assign new_list><#list reportData.daily as list><#if list?string('M')?number=6 && list?string('Y')?number=2017>${list?string("dd/MM/yyyy")}</#if></#list></#assign>${new_list?last}
if I remove the "?last" it will show me a sublist for all dates for June-2017 but once i add "?last" i get:
For "?last" left-hand operand: Expected a sequence, but this has evaluated to a string (wrapper: f.t.SimpleScalar):

You get that error because <#assign new_list>...</#assign> captures the raw output printed, which is not a sequence. If you really have to do this in template, put an #if inside the #list which only prints the current item if the next one is in a different month. (You can peek at the next item inside <#list xs as x>...</#list> like xs[x?index + 1]) But, you aren't supposed to do such data processing in a template...

Related

NIFI: Unable to extract two values from a list during each iteration over a loop

I would like to retrieve large SQL dump between date ranges. For the same, I constructed a loop over a date list, which intends to extract adjacent fields. Unfortunately, in my case, it doesnt work as planned.
Following is my flow:
Replace Text: Takes flowfile content date list as all_first_dates
Initialize Count:
While Loop:
Get first and adjacent dates:
However, on seeing the queue, I get the first and second as this:
Whereas, I desired as 2016-01-01 and 2016-01-02 for first and second respectively on my first iteration and so on.
check the description of the getDelimitedField function and it's parameters:
Description: Parses the Subject as a delimited line of text and returns just a single field from that delimited text.
Arguments:
index: The index of the field to return. A value of 1 will return the first field, a value of 2 will return the second field, and so on.
delimiter: Optional argument that provides the character to use as a field separator. If not specified, a comma will be used. This value must be exactly 1 character.
...
you are not passing the second parameter, so the coma used to split the subject, and you got the whole subject as one element in result.

Freemarker: Output comma separated list as an array

I have a table that has a field that contains a comma separated list of order IDs. What I am trying to do is output each of those IDs separately so that I can use them to look up their corresponding order details in another table.
Does anyone know of a good way to do this?
So far I have tried:
<#data Alerts_test_table as alerts_test>
<#filter
CUSTOMER_ID_=CONTACTS_LIST.CUSTOMER_ID_1>
<#fields AD_ID_LIST>
<#assign seq = ['${alerts_test.AD_ID_LIST}']>
<#list seq?chunk(1) as row><#list row as cell>
${cell}
</#list> </#list>
</#data>
But this just outputs it as a line of text.
Let's say you have comma separated ID-s in idsString, and you want to iterate though the ID-s one by one. Then:
Data-model (with http://try.freemarker.org/ syntax):
idsString = "11, 22, 33"
Template:
<#list idsString?split(r'\s*,\s*', 'r') as idString>
${idString}
</#list>
However, in the template you have posted I see many strange things, so some ideas/pointers:
Be sure that alerts_test.AD_ID_LIST is indeed a String, not a List that you can list directly, without ?split-ing. If it's a String, then '${alerts_test.AD_ID_LIST}' is ultimately the same as alerts_test.AD_ID_LIST. In general, you never need an empty string literal and an ${} in it. It's not useful (but sometimes harmful, as it converts non-string values to string).
?chunk(1) is not useful. The point of ?chunk is to slice a list to smaller lists, but if those smaller lists are to be 1 long, then you might as well just list the items of the original list.
There are no such directives as #data and #filter. Is this some forked FreeMarker version?
If the ID is a number that you need to pass to some API that expects a number, then you will have to convert it to number like idString?number.

Soundex returns 0 for every character

I have this function which converts a word to a soundex value, but it is returning all letters as 0. My last name, Smith, should by S530, but returns S000, for example.
Link for code (since it's too long to put on here): http://pastebin.com/9hESxV7P
I had it log the value of letterArray and it does evaluate to an array of all the letters in my last name. It has to be something in the for ... in loop. Any help would be great. Thanks!
changing this line
let trimmedWord = word.uppercaseString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
it produce S530

XPath 2.0:reference earlier context in another part of the XPath expression

in an XPath I would like to focus on certain elements and analyse them:
...
<field>aaa</field>
...
<field>bbb</field>
...
<field>aaa (1)</field>
...
<field>aaa (2)</field>
...
<field>ccc</field>
...
<field>ddd (7)</field>
I want to find the elements who's text content (apart from a possible enumeration, are unique. In the aboce example that would be bbb, ccc and ddd.
The following XPath gives me the unique values:
distinct-values(//field[matches(normalize-space(.), ' \([0-9]\)$')]/substring-before(., '(')))
Now I would like to extent that and perform another XPath on all the distinct values, that would be to count how many field start with either of them and retreive the ones who's count is bigger than 1.
These could be a field content that is equal to that particular value, or it starts witrh that value and is followed by " (". The problem is that in the second part of that XPath I would have refer to the context of that part itself and to the former context at the same time.
In the following XPath I will - instead of using "." as the context- use c_outer and c_inner:
distinct-values(//field[matches(normalize-space(.), ' \([0-9]\)$')]/substring-before(., '(')))[count(//field[(c_inner = c_outer) or starts-with(c_inner, concat(c_outer, ' ('))]) > 1]
I can't use "." for both for obvious reasons. But how could I reference a particular, or the current distinct value from the outer expression within the inner expression?
Would that even be possible?
XQuery can do it e.g.
for $s
in distinct-values(
//field[matches(normalize-space(.), ' \([0-9]\)$')]/substring-before(., '(')))
where count(//field[(. = $s) or starts-with(., concat($s, ' ('))]) > 1
return $s

last entry in a loop

I have an associative array and I generate a lot of different things with this array.
The output I need has the form
aa, ab, ac, ad, af, ak, az
So the last entry does not have a comma after it
{section name=i loop=$aColums}
{if $aColums[i].contshow eq 'y'}
{$aColums[i].Name}
{endif}
{/section}
My problem is that I don't know when I've reached the last value, which has the contshow=y attribute. So my next thought was to apply the comma before I write aColums[i].Name. But here I have a similar problem becuase I don't know when I've reached the first value with contshow=y.
Does anyone have a suggestion?
There is an alternative method, using the section's .last property.
{section name=i loop=$aColums}
{if $aColums[i].contshow eq 'y'}
{$aColums[i].Name}{if $smarty.section.i.last eq false}, {/if}
{endif}
{/section}
This adds a ', ' after every output Name - unless it's the last iteration of the {section}. I'm assuming that your $aColums array data doesn't already have commas tacked on.
You also have another option - pregenerate this string in PHP using implode:
$aColumsString = implode(', ', $aColums);
$smarty->assign('aColumsString', $aColumsString);
Then just output to the template as needed. If you require the list with commas more than once, this is probably the more efficient method. If you need it once, it's probably a toss-up effiency-wise.
The general way to deal with this is to write the commas before each element. In this way, the special-case is the first element (which doesn't need a preceding comma) rather than the last, and it's a lot easier to work out whether you're seeing the first element or not. Just set a boolean flag to true initially, then set it to false after matching an entry.
Mind you, Smarty might have a utility function for "joining" the array with a given string (comma, in this case). If such a function exists, using it directly would be the best option.
In Smarty 3, this is much simplified:
{foreach $aColumns AS $aCol}
{$aCol}{if not $aCol#last}, {/if}
{/foreach}

Resources