I am trying to hide users that aren't in filtered users list.
For this, I am using this code
_.each(users, function (user) {
var display_type = filtered_users.hasOwnProperty(user.email)? "block" : "none";
$("label[for='" + user.email + "']").css({"display":display_type});
});
users
filtered_users
$("label[for='" + user.email + "']").css({"display":display_type})
<label class="checkbox" for="user1@gmail.com">
<input type="checkbox" name="user" value="user1@gmail.com"> Cordelia Lear (cordelia@zulip.com)
</label>
<label class="checkbox" for="user2@gmail.com">
<input type="checkbox" name="user" value="user2@gmail.com"> Cordelia Lear (cordelia@zulip.com)
</label>
$("label[for='" + user.email + "']").css({"display":display_type})
This $("label[for='" + user.email + "']")
is the part the slows you down. For every user, jquery's sizzle engine have to go over all of the labels in the page, and choose the exact one, so it's at least o(n) * o(n) for iterating the users - o(n2).
To solve that you can create a map of labels by emails once (the same thing you do for filtered_users
), and then with o(1), find the element and change the display:
var usersMap = $('.users')
.find('label')
.toArray()
.reduce(function(map, user) {
var $user = $(user);
var email = $user.attr('for');
map[email] = $user;
return map;
}, {});
var users = [
{ email: 'user1@gmail.com' },
{ email: 'user2@gmail.com'}
];
var filtered_users = { 'user1@gmail.com': true };
users.forEach(function(user) {
var display_type = filtered_users.hasOwnProperty(user.email) ? "block" : "none";
usersMap[user.email].css({
"display": display_type
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="users">
<label class="checkbox" for="user1@gmail.com">
<input type="checkbox" name="user" value="user1@gmail.com">Cordelia Lear (cordelia@zulip.com)
</label>
<label class="checkbox" for="user2@gmail.com">
<input type="checkbox" name="user" value="user2@gmail.com">Cordelia Lear (cordelia@zulip.com)
</label>
</div>