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.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Mahmoud Saleh
  • 31,861
  • 113
  • 313
  • 484

2 Answers2

7

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.

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Just don't use arrays if you want to do a bit more than just holding the data. Use collections then. – BalusC Dec 20 '11 at 14:38
  • well, i am using it on an input attribute, but the method is not getting called: `checked="#{utils.contains(myBean.array,'myBean.someIndicator') ? 'checked' : ''}"` – Mahmoud Saleh Dec 20 '11 at 14:55
  • 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. – BalusC Dec 20 '11 at 14:58
  • aha, got you, and no i can't see EL errors, shouldn't an exception thrown if there's an EL error ? – Mahmoud Saleh Dec 20 '11 at 15:04
  • 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. – BalusC Dec 20 '11 at 15:11
  • the above method doesn't work so fine, when the value of the input is an int. – Mahmoud Saleh Dec 21 '11 at 14:59
  • meaning if the value is 1 instead of u1 in this case equality will fail. – Mahmoud Saleh Dec 21 '11 at 15:15
  • 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. – Mahmoud Saleh Dec 21 '11 at 15:20
  • 1
    Just use `Integer` instead or modify the method to loop over the array instead of converting `int[]` to `List` (which is invalid). – BalusC Dec 21 '11 at 15:21
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>
Benjamin W.
  • 33,075
  • 16
  • 78
  • 86
  • This simple solution helped me as I wanted to check a `${ param.stringArray }` of checkbox values. – ruhong Sep 27 '16 at 05:00