问题
Hoping for some guidance.
Consider this snippet:
val q = (for {
(d, o) <- dx innerJoin ox on (_.user === _.id)
} yield(d,o))
"div" #> q.map { case (x, y) =>
{
".dF1 *" #> x.name &
".dF2 *" #> y.id
}
}
in this query, I have two tables, where table "ox" is a list of people, and "dx" is a list of items associated with those people. As it is written, it works good, but I end up creating one row for each item that a person has. So assume three users, first two have two items, and last one has 1, i get five rows:
<div class="dF1">[user1]</div><div class="dF2">[item1]</div>
<div class="dF1">[user1]</div><div class="dF2">[item2]</div>
<div class="dF1">[user2]</div><div class="dF2">[item1]</div>
<div class="dF1">[user2[</div><div class="dF2">[item2]</div>
<div class="dF1">[user3]</div><div class="dF2">[item3]</div>
What I'd like to do is create a single row for each user, and inside of the dF2 field create multiple divs, one for each item. The layout would then be:
<div class="dF1">[user1]</div><div class="dF2">[item1] [item2]</div>
<div class="dF1">[user2]</div><div class="dF2">[item1] [item2]</div>
<div class="dF1">[user3]</div><div class="dF2">[item1]</div>
How can I do this? Do I need to use an intermediary collection?
回答1:
You have two options here, you can either use the database to return a collection grouped by a field or you can use Scala to group your collection. If you use the database, you will be limited to grouping by a field, like x.name
, but your execution will likely be more efficient. If you group with Scala you'll be able to group by the entire object x
, but you will end up doing more processing and object creation. You'd need to decide which is best for you.
Now, that said - let's assume we're using Scala. You would do something like this:
"div" #> q.groupBy(_._1).map { case (x, y) =>
{
".dF1 *" #> x.name &
".dF2 *" #> y.map{ case (x2, y2) => y2.id}.mkString(" ")
}
}
Instead of working directly with the List
containing D
and O
from your query, the groupBy
will create a list of type: Map[D, List[(D, O)]]
. In the example above, I am just combining the id
field of your o
into a single string to output which looked like the example you requested.
Instead of a single string, you could also have your second map return a CssSel
to do further transformations. This example which will look for <div class="dF2SubDiv"></div>
nested in the div
that has the class dF2
:
"div" #> q.groupBy(_._1).map { case (x, y) =>
{
".dF1 *" #> x.name &
".dF2" #> y.map{ case (x2, y2) =>
".dF2SubDiv *" #> y2.id
}
}
}
If you would rather use Slick to do the groupBy, you could find more info on it here and here.
来源:https://stackoverflow.com/questions/19173423/lift-grouping-items-during-css-selector-transform