Collection/Array contains method
Asked Answered
M

2

5

i was wondering if there's contains method for collections/array in EL 2.2 or i will have to make a custom one ?

REQUIREMENT: i have a string array, and i want to find if it contains a specific string.

CASE: i am looping on list of input checkboxes to render them, and i want to check the current checkbox, if it's value exists in the array of checkboxes.

UPDATE:

  • is such method is available in EL?

  • If such method is not available, then please provide your suggestion for best performance method for a string array contains an element.

Mitchellmitchem answered 20/12, 2011 at 14:19 Comment(0)
F
8

For a Collection it's easy, just use the Colleciton#contains() method in EL.

<h:panelGroup id="p1" rendered="#{bean.panels.contains('p1')}">...</h:panelGroup>
<h:panelGroup id="p2" rendered="#{bean.panels.contains('p2')}">...</h:panelGroup>
<h:panelGroup id="p3" rendered="#{bean.panels.contains('p3')}">...</h:panelGroup>

For an Object[] (array), you'd need a minimum of EL 3.0 and utilize its new Lambda support.

<h:panelGroup id="p1" rendered="#{bean.panels.stream().anyMatch(v -> v == 'p1').get()}">...</h:panelGroup>
<h:panelGroup id="p2" rendered="#{bean.panels.stream().anyMatch(v -> v == 'p2').get()}">...</h:panelGroup>
<h:panelGroup id="p3" rendered="#{bean.panels.stream().anyMatch(v -> v == 'p3').get()}">...</h:panelGroup>

If you're not on EL 3.0 yet, you'd need to create a custom EL function. For a concrete example, see How to create a custom EL function to invoke a static method? E.g.

public static boolean contains(Object[] array, Object item) {
    return Arrays.asList(array).contains(item);
}

which is registered as

<function>
    <function-name>contains</function-name>
    <function-class>com.example.Functions</function-class>
    <function-signature>boolean contains(java.lang.Object[], java.lang.Object)</function-signature>
</function>

and to be used as

<h:panelGroup ... rendered="#{func:contains(bean.panels, 'u1')}">

This is not available in JSTL. There's a fn:contains(), but that works on String values only.

Ferdinand answered 20/12, 2011 at 14:31 Comment(9)
Just don't use arrays if you want to do a bit more than just holding the data. Use collections then.Ferdinand
well, i am using it on an input attribute, but the method is not getting called: checked="#{utils.contains(myBean.array,'myBean.someIndicator') ? 'checked' : ''}"Mitchellmitchem
Are there any EL errors? By the way, the way how you use checked is not entirely right. A checkbox/radiobutton is checked when the whole attribute is present, regardless of its value. You basically want to print the attribute name instead of the attribute value conditionally.Ferdinand
aha, got you, and no i can't see EL errors, shouldn't an exception thrown if there's an EL error ?Mitchellmitchem
Oh, I see, you're using . instead of :. Since #{utils} doesn't exist as managed bean, nothing will happen. To call functions, you need #{prefix:functionName()} with : instead.Ferdinand
the above method doesn't work so fine, when the value of the input is an int.Mitchellmitchem
meaning if the value is 1 instead of u1 in this case equality will fail.Mitchellmitchem
i have to convert item to string before comparing to work fine, but i am afraid that this may cause a problem with large numbers.Mitchellmitchem
Just use Integer instead or modify the method to loop over the array instead of converting int[] to List<int> (which is invalid).Ferdinand
M
2

If you are using a String[], you can first concatenate all the elements of an array into a string using fn:join():

<c:set var="concat" value="${fn:join(myArray, '-')}"/>

And then use the fn:contains()` function in order to check if a value exists in that string:

<c:if test="${fn:contains(concat, 'myString')}">Found!</c:if>
Mcginty answered 26/4, 2016 at 16:14 Comment(1)
This simple solution helped me as I wanted to check a ${ param.stringArray } of checkbox values.Reductive

© 2022 - 2024 — McMap. All rights reserved.