Reputation: 23
I have any array in velocity which has duplicate values too. I want to create an array with unique values where all the values are sorted based on their count/frequency in the original array.
For example:
#set($y = 0)
#set ($pagelist = [])
#foreach($label in $page.labels)
#set($pinnedPages = $repository.getContentByLabel("$!label"))
#set($currentpage = $page)
## Display the page that has a label that matches current page label.
#foreach($page in $pinnedPages)
#if($page != $currentpage)
## Display the page name as a list item.
#set ($pagelistswallow = $pagelist.add($page.title))
<li>$pagelist.get($y)</li>
#set($y = $y + 1)
#end
#end
#end
The pagelist array has page names and few of them occur multiple times in this array . I need an array with unique page names sorted in the order of their frequency in the original pagelist array.
Can anyone help? I have tried but my code is not working...
Upvotes: 0
Views: 355
Reputation: 4130
You can do :
#foreach($label in $page.labels)
#set($pinnedPages = $repository.getContentByLabel("$!label"))
#set($currentpage = $page)
## Prepare a map (title -> occurrences) of pages
## which have a label that matches current page label.
#set($pagemap = {})
#foreach($subpage in $pinnedPages)
#if($subpage != $page)
#set($junk = $pagemap.put(
$page.title,
$pagemap.getOrDefault($page.title, 0) + 1))
#end
#end
## Calculate a map (occ, title) -> title
#set($pagetmp = {})
#foreach($entry in $pagemap.entrySet())
#set($junk = $pagetmp.put(
"${entry.value}_${entry.key}",
$entry.key))
#end
## Display those related pages by increasing
## number of occurrences (just reverse the array
## for a decreasing order)
#set($pagekeys = $pagetmp.keySet().stream().sorted().toArray())
#foreach($key in $pagekeys)
<li>(label: $label) $pagetmp.get($key)</li>
#end
#end
The need to use sorted()
explicitely comes from the fact that Velocity empty maps are LinkedHashMap
, hence keys order is a hash, not the natural order.
As a variant, to be able to display the number of occurrences, you can easily adapt this code to have $pagetmp
values be a map { occ, title }
.
If you're using Velocity 1.6, you have to split the instruction #set($junk = ...)
into :
#set($subinit = $pagemap.getOrDefault($pagetitle, 0) + 1)
#set($junk = $pagemap.put($page.title, $ubinit))
Upvotes: 1