我有一系列项目terms)
,它们将<option>
标记放在<select>
中。如果其中任何一项都在另一个数组中termsAlreadyTaking
),他们应该先被删除。我是这样做的:
// If the user has a term like "Fall 2010" already selected, we don't need that in the list of terms to add.
for (var i = 0; i < terms.length; i++)
{
for (var iAlreadyTaking = 0; iAlreadyTaking < termsAlreadyTaking.length; iAlreadyTaking++)
{
if (terms[i]['pk'] == termsAlreadyTaking[iAlreadyTaking]['pk'])
{
terms.splice(i, 1); // remove terms[i] without leaving a hole in the array
continue;
}
}
}
有更好的方法吗?感觉有点笨拙。
我正在使用jQuery,如果它有所作为。
更新基于@Matthew Flaschen的回答:
// If the user has a term like "Fall 2010" already selected, we don't need that in the list of terms to add.
var options_for_selector = $.grep(all_possible_choices, function(elem)
{
var already_chosen = false;
$.each(response_chosen_items, function(index, chosen_elem)
{
if (chosen_elem['pk'] == elem['pk'])
{
already_chosen = true;
return;
}
});
return ! already_chosen;
});
它在中间变得更加冗长的原因是$.inArray()
返回false,因为我正在寻找的副本在==
意义上并不严格相等。但是,它们的所有值都是相同的。我能说得更简洁吗?
答案 0 :(得分:3)
var terms = $.grep(terms, function(el)
{
return $.inArray(el, termsAlreadyTaking) == -1;
});
这仍然具有m * n性能(m和n是数组的长度),但只要它们相对较小,它就不应该是一个大问题。要获得m + n,您可以使用哈希表
请注意,ECMAScript提供了类似的数组。filter和数组。indexOf。但是,它们尚未在所有浏览器中实现,因此您必须使用MDC实现作为后备。由于您使用的是jQuery,grep和inArray(在可用时使用原生indexOf)更容易。
编辑:
你可以这样做:
var response_chosen_pk = $.map(response_chosen_items, function(elem)
{
return elem.pk;
});
var options_for_selector = $.grep(all_possible_choices, function(elem)
{
return $.inArray(elem.pk, response_chosen_pk) == -1;
});
答案 1 :(得分:0)
http://github.com/danstocker/jorder
在termsAlreadyTaking上创建一个jOrder表,并用pk索引它。
var table = jOrder(termsAlreadyTaking)
.index('pk', ['pk']);
然后你可以更快地搜索:
...
if ([] == table.where([{ pk: terms[i].pk }]))
{
...
}
...