查看数组是否包含对象的更好方法是什么?

时间:2010-07-04 05:07:54

标签: javascript arrays object

我有一系列项目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,因为我正在寻找的副本在==意义上并不严格相等。但是,它们的所有值都是相同的。我能说得更简洁吗?

2 个答案:

答案 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 }]))
{
    ...
}
...