The documentation for the ui:repeat tag in JSF 2.0 says you can iterate over a ResultSet but my code:
<ui:repeat value="#{bean.resultSet}" var="row" varStatus="status">
#{row.string("mySQLColumn")}
</ui:repeat>
produces this error:
javax.faces.FacesException: Iteration start index is greater than the number of available rows.
at com.sun.faces.facelets.component.UIRepeat.validateIterationControlValues(UIRepeat.java:682)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:505)
at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:974)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1756)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
Even though it seems to be supported as argument for iteration, it would be best to first transform it to a List and then iterate.
That way you won't be propagating the database-access technology to the view layer.
Related
Please consider the following strings array:
let strings = ["str1", "str2", "str10", "str20"]
Let's assume that what required is to get the first element (String) which contains 5 characters, I could get it by using filter(_:) as follows:
let filterString = strings.filter { $0.count == 5 }.first
print(filterString!) // str10
but after reviewing the first(where:) method, I recognized that I will be able to get the same output:
let firstWhereString = strings.first(where: { $0.count == 5 })
print(firstWhereString!) // str10
So what is the benefit of using one instead of the other? is it only about that the filter(_:) returns a sequence and the first(where:) returns a single element?
Update:
I noticed that the filter(_:) took 5 times to do such a process, while first(where:) took 4 times:
You are correct in observing that filter(_:) returns all elements that satisfy a predicate and that first(where:) returns the first element that satisfy a predicate.
So, that leaves us with the more interesting question of what the difference is between elements.filter(predicate).first and
elements.first(where: predicate).
As you've already noticed they both end up with the same result. The difference is in their "evaluation strategy". Calling:
elements.filter(predicate).first
will "eagerly" check the predicate against all elements to filter the full list of elements, and then pick the first element from the filterer list. By comparison, calling:
elements.first(where: predicate)
will "lazily" check the predicate against the elements until it finds one that satisfies the predicate, and then return that element.
As a third alternative, you can explicitly use "a view onto [the list] that provides lazy implementations of normally eager operations, such as map and filter":
elements.lazy.filter(predicate).first
This changes the evaluation strategy to be "lazy". In fact, it's so lazy that just calling elements.lazy.filter(predicate) won't check the predicate against any elements. Only when the first element is "eagerly" evaluated on this lazy view will it evaluate enough elements to return one result.
Separately from any technical differences between these alternatives, I'd say that you should use the one that most clearly describes your intentions. If you're looking for the first element that matches a criteria/predicate then first(where:) communicates that intent best.
I believe we should start from considering each method separately and their purpose.
filter(_:) is not purposefully designed to prepare us to obtain first element. It is about filtering and that's it. It merely returns us a sequence. first can be used after filter, but that's just an instance of usage, a possible case. first is called for a collection and if we want, of course we are free to use it directly after filter.
But first(where:) was designed to filter and return a single element and is evidently the go-to approach to accomplish that kind of a task. That said, it is easy to presume that it's also preferred from performance perspective. As mentioned, we filter entire sequence, but with first(where:) we only process the portion of a sequence until condition is met.
So the other day I had my colleague review my code and he saw that I was using array[0], in Java terms this is basically getting the first element of the array. I did this several times for different purposes, all of which is to get the first element in an array/collection, for example list.get(0), to which he strongly disagreed with.
His argument was that somebody from non-programming background would have problem understanding it and using 0 in such cases is basically hard-coding, which is bad practice. I google-ed several times and all suggestions to getting the first element in an array or any collection is providing them the index, which is 0 in this case.
Could anyone provide me with a suggestion on getting the first element in a meaningful way?
Try using linkedlist's getfirst method to get the first element of the list.
If you were to use an ArrayList is backed by an array and hence its perfectly valid to use index as 0 to get first element.
I want to use ui:repeat to fill values of an integer array which is originally empty, from inputText. I followed the explanation in here, but it did't work for me. My UI is:
<ui:repeat value="#{controllerBean.schedule.scheduleTimes}" var="v" varStatus="loop">
<h:outputText value="Shedulte Time #{loop.index + 1}">
</h:outputText>
<p:inputText value="#{controllerBean.schedule.scheduleTimes[loop.index]}">
</p:inputText>
</ui:repeat>
contollerBean is the managed bean, schedule is model and scheduleTimes is Integer[] array in my model with setter and getter. After providing some values on ui, the values of the array at each index is still null.
You need a converter to Integer because in JSF all values are by default treated as String.
<ui:repeat value="#{controllerBean.schedule.scheduleTimes}" var="v" varStatus="loop">
<h:outputText value="Shedulte Time #{loop.index + 1}">
</h:outputText>
<p:inputText value="#{controllerBean.schedule.scheduleTimes[loop.index]}" converter="javax.faces.Integer">
</p:inputText>
</ui:repeat>
Now the example works for me like a charm.
My previous answer is incorrect because JSF automatically converts primitive types. A converter is however required for Collections because expected type cannot be determined at runtime.
Nevertheless the example works with a converter or without. Therefore please make sure that controllerBean has scope other than non-scoped (without scope annotation). Otherwise the bean is recreated each time you access it.
Well, also with request scope my code works fine. Please check the
example I'm using
I replaced primefaces p:inputText with pure JSF h:inputText but I don't think it matters. I also added some html table tags to do a formatting.
As you can see in server logs values are set properly.
Usually in protractor you can select singular element with:
element(protractor.By.css('#fdfdf'));
Occasionally you get something like this:
element(protractor.By.css('.dfdf'));
which potentially has more than one element. What's the correct way to select an index from a locator that locates multiple elements, and still contain the protractor's methods for sending Keys?
You can get an indexed element from an array returned with
// Get the 5th element matching the .dfdf css selector
element.all(by.css('.dfdf')).get(4).sendKeys('foo');
If you want to get the first element then
element.all(by.css('.dfdf')).first();
element.all(by.css('.dfdf')).get(0);
Try this one. It will work:
element.all(by.css('.dfdf')).get(4).getText();
I don't know why xpath is so much underestimated but you can solve thousands of problems with it, including this one
let elem = element(by.xpath('(//div//a)[3]'))
You can specify the number of element to use. Keep in mind the numbers start from 1, not 0 as usually in js
In my graph database I have Branches and Leaves. Branches can "contain" Leaves and Branches can "contain" Branches.
How, using Gremlin, can I find all leaves for a given branch, that are directly or indirectly related to it?
I got this to work in Cypher:
START v=node(1) MATCH v-[:contains*1..2]->i RETURN v,i
Where the *1..2 means "friends and friends of friends".
I thought maybe LoopV was the way forward, but I just get an Exception:
Error reading JArray from JsonReader. Current JsonReader item is not an array: String
You can do the following in Gremlin 1.4+.
g.v(1).out('contains').loop(1){true}{it.out('contains').count() == 0}
This says:
Start at vertex with id 1
Take the outgoing "contains" edges.
Loop over the out('contains') section.
Loop "infinitely" (make sure your tree doesn't have loops in it)
Emit only those vertices touched that don't have more outgoing 'contains'-edges. (i.e. the leaves)
However, looking at what you wanted from Cypher, it looks like you only want 2 steps. Thus, to do that, simply do:
g.v(1).out('contains').loop(1){it.loops < 3}
Perhaps I misunderstood your question --- either way, that should give you enough to play with.