Вы можете получить довольно чистую реализацию, используя std :: map, чтобы подсчитать вхождения, а затем полагаться на std :: list :: sort, чтобы отсортировать полученный список слов. Например:
std::list<std::string> duplicateWordList(const std::vector<std::string>& words) {
std::map<std::string, int> temp;
std::list<std::string> ret;
for (std::vector<std::string>::const_iterator iter = words.begin(); iter != words.end(); ++iter) {
temp[*iter] += 1;
// only add the word to our return list on the second copy
// (first copy doesn't count, third and later copies have already been handled)
if (temp[*iter] == 2) {
ret.push_back(*iter);
}
}
ret.sort();
return ret;
}
Использование std :: map кажется немного расточительным, но оно выполняет свою работу.
Вы вызываете LoadRolesDropdown () после LoadApplicationUsers (), но внутри LoadApplicationUsers () есть ajax-вызов, который выполняется асинхронно, занимает время.
Переместите LoadRolesDropdown внутри LoadApplicationUsers и вызовите его после цикла each ().
function LoadApplicationUsers(appID) {
$('#grdUsers').DataTable().clear();
$('#grdUsers').DataTable().destroy();
GetUserRoles().done(function (users) {
$.each(users, function (index, user) {
if (user.applicationID == appID) {
$("#grdUsers tbody").append(`
<tr>
<td class="text-center"><button type="button" class="btn btn-sm btn-danger deleteuser"> X </button></td>
<td class="d-none userID">${ user.userID}</td>
<td class="d-none userID">${ user.roleID}</td>
<td>${ user.username}</td>
<td><select class="roles"></select></td>
<td>${ user.roleName}</td>
</tr>
`);
}
});
$('#grdUsers').DataTable({
"paging": false,
});
LoadRolesDropdown(appID);
});
}
Вы можете вызвать функцию LoadRolesDropdown()
после того, как DOM закончит рендеринг. В jQuery вы можете сделать это,
$(document).ready(function(){
LoadRolesDropdown(WITH_APP_ID);
})