Это:
std::sort(std::begin(shapes), std::end(shapes));
использует сравнение по умолчанию sort
, то есть operator<
. operator<
в std::variant
определяется как как , сравнивая по индексам сначала , а затем, если оба варианта содержат одну и ту же альтернативу, сравнивая базовые значения.
Другими словами:
using V = std::variant;
V v1(static_cast(42)); // holds a char
V v2(15); // holds an int
v1 < v2; // this is true, because 'char' comes before 'int'
Итак, когда вы сортируете свои variant
, вы не сортируете по областям. Вы эффективно сортируете по кортежу (index, area)
. Который мы могли бы написать длинным путем:
std::sort(std::begin(shapes), std::end(shapes),
[](auto const& lhs, auto const& rhs)
{
auto tied = [](auto const& x) {
return std::make_tuple(
// the index
x.index(),
// the area
std::visit([](auto const& e){ return e.area(); }, x)
);
};
return tied(lhs) < tied(rhs);
});
Это дает тот же порядок, что и в вашем первоначальном примере. А затем, если вы удалите x.index()
часть кортежа, вы получите тот порядок, который вам нужен.
Но короче просто использовать многократное посещение:
std::sort(std::begin(shapes), std::end(shapes),
[](auto const& lhs, auto const& rhs)
{
std::visit([](auto const& x, auto const& y){
return x.area() < y.area();
}, lhs, rhs);
});
, которое станет еще короче в C ++ 20 с диапазонами и проекциями:
std::ranges::sort(shapes, std::less(), [](auto const& x){
return std::visit([](auto const& e){ return e.area(); }, x);
});
Ниже работ кода для меня
первый я определил partnerTypesMap
как ниже в стороне сервера,
Map<String, String> partnerTypes = new HashMap<>();
после добавления значений к ней я добавил объект к model
,
model.addAttribute("partnerTypesMap", partnerTypes);
При рендеринге страницы, которую я использую ниже foreach
для печати их один за другим.
<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
<form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
Точно так же, как и в обычном коде Java.
for (Map.Entry<String, String> entry : countries.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// ...
}
Однако , скриптлеты (необработанный код Java в файлах JSP, те <%%>
вещей) считаются плохой практикой . Я рекомендую установить JSTL (просто поместите файл JAR в / WEB-INF / lib
и объявите необходимые библиотеки тегов поверх JSP). Он имеет тег
, который может выполнять итерацию среди других Map
s. Каждая итерация возвращает вам Map.Entry
, который, в свою очередь, имеет методы getKey ()
и getValue ()
.
Вот базовый пример:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${map}" var="entry">
Key = ${entry.key}, value = ${entry.value}<br>
</c:forEach>
Таким образом, ваша конкретная проблема может быть решена следующим образом:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<select name="country">
<c:forEach items="${countries}" var="country">
<option value="${country.key}">${country.value}</option>
</c:forEach>
</select>
Вам нужен сервлет
или ServletContextListener
, чтобы поместить $ {country}
в нужную область. Если предполагается, что этот список основан на запросах, тогда используйте Servlet
doGet ()
:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> countries = MainUtils.getCountries();
request.setAttribute("countries", countries);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
}
Или, если этот список должен быть константой всего приложения, затем используйте ServletContextListener
contextInitialized ()
, чтобы он был загружен только один раз и сохранен в памяти:
public void contextInitialized(ServletContextEvent event) {
Map<String, String> countries = MainUtils.getCountries();
event.getServletContext().setAttribute("countries", countries);
}
В обоих случаях будут доступны страны
в EL от $ {country}
.
Надеюсь, это поможет.
В зависимости от того, что вы хотите выполнить в цикле, вместо этого выполните итерацию по одному из следующих вариантов:
country.keySet ()
country.entrySet ()
country.values ()