JavaScript如何检查数组是否包含对象?

How do I check if an array includes an object in JavaScript?

找出一个javascript数组是否包含一个对象的最简洁和有效的方法是什么?

这是我唯一知道的方法:

1
2
3
4
5
6
7
8
function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

有没有更好、更简洁的方法来实现这一点?

这与堆栈溢出问题密切相关。在JavaScript数组中查找项的最佳方法是什么?它使用indexOf在数组中查找对象。


当前的浏览器有Array#includes,它确实做到了这一点,得到了广泛的支持,并且对旧的浏览器有多个填充。

1
2
> ['joe', 'jane', 'mary'].includes('jane');
true

您也可以使用Array#indexOf,这不是很直接,但对于过时的浏览器不需要polyfill。

jquery提供了$.inArray,功能上相当于Array#indexOf

javascript实用程序库underline.js提供了_.contains(list, value),别名_.include(list, value),如果传递了一个javascript数组,这两个库都会在内部使用indexof。

其他一些框架提供了类似的方法:

  • Dojo工具包:dojo.indexOf(array, value, [fromIndex, findLast])
  • 原型:array.indexOf(value)
  • moootools:array.indexOf(value)
  • 莫奇基特:江户十一〔15〕。
  • 阿贾克斯女士:array.indexOf(value)
  • 分机:Ext.Array.contains(array, value)
  • 罗达什:_.includes(array, value, [from])(4.0.0之前是_.contains)
  • ecmascript 2016:array.includes(value)

请注意,有些框架将此作为函数实现,而另一些框架将此函数添加到数组原型中。


更新:正如@orip在评论中提到的,链接的基准测试是在2008年完成的,因此结果可能与现代浏览器无关。但是,您可能需要它来支持非现代浏览器,而且它们可能从那时起就没有更新过。总是为自己测试。

正如其他人所说,通过数组进行迭代可能是最好的方法,但是已经证明减少while循环是最快的迭代javascript的方法。因此,您可能需要重写代码,如下所示:

1
2
3
4
5
6
7
8
9
function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

当然,您也可以扩展数组原型:

1
2
3
4
5
6
7
8
9
Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

现在您可以简单地使用以下内容:

1
2
alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false


indexOf可能,但它是"ECMA-262标准的javascript扩展;因此,它可能不存在于该标准的其他实现中。"

例子:

1
2
3
[1, 2, 3].indexOf(1) => 0
["foo","bar","baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS Microsoft不提供这种替代方法,但是如果您愿意,可以在Internet Explorer(以及其他不支持indexOf的浏览器)中向阵列添加类似的功能,就像谷歌快速搜索显示的那样(例如,这一个)。


ecmascript 7介绍了Array.prototype.includes

它可以这样使用:

1
2
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false

它还接受可选的第二个参数fromIndex

1
2
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true

与使用严格相等比较的indexOf不同,includes使用samevaluezero相等算法进行比较。这意味着您可以检测数组是否包含NaN

1
[1, 2, NaN].includes(NaN); // true

indexOf不同,includes没有跳过缺少的指数:

1
new Array(5).includes(undefined); // true

目前,它仍然是一个草稿,但可以多填充,使其在所有浏览器上都能工作。


b为数值,a为数组。返回truefalse

1
2
3
function(a, b) {
    return a.indexOf(b) != -1
}


最前面的答案假设是基元类型,但是如果您想了解数组是否包含具有某些特征的对象,array.prototype.some()是一个非常优雅的解决方案:

1
2
3
4
const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

它的好处在于,一旦找到元素,迭代就会中止,这样就可以保存不必要的迭代周期。

此外,它还非常适合于if语句,因为它返回一个布尔值:

1
2
3
if (items.some(item => item.a === '3')) {
  // do something
}

*正如Jamess在评论中指出的那样,截至2018年9月的今天,Array.prototype.some()得到了充分的支持:canius.com支持表


下面是一个与javascript 1.6兼容的Array.indexOf实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (!Array.indexOf) {
    Array.indexOf = [].indexOf ?
        function(arr, obj, from) {
            return arr.indexOf(obj, from);
        } :
        function(arr, obj, from) { // (for IE6)
            var l = arr.length,
                i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;
            i = i < 0 ? 0 : i;
            for (; i < l; i++) {
                if (i in arr && arr[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
}


用途:

1
2
3
4
5
6
7
8
9
10
function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

// Usage
if(isInArray(my_array,"my_value"))
{
    //...
}


扩展javascript Array对象是一个非常糟糕的主意,因为您将新的属性(自定义方法)引入for-in循环中,这会破坏现有的脚本。几年前,原型库的作者不得不重新设计他们的库实现,以删除这类东西。

如果您不需要担心与页面上运行的其他javascript的兼容性,那么就开始吧,否则,我建议您使用更笨拙但更安全的独立函数解决方案。


考虑一秒钟,如果您多次进行此调用,则使用关联数组a map to do lookups using a hash function会更有效。

https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/map


一班轮:

1
2
3
function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}


我使用以下方法:

1
2
3
4
5
6
7
8
Array.prototype.contains = function (v) {
    return this.indexOf(v) > -1;
}

var a = [ 'foo', 'bar' ];

a.contains('foo'); // true
a.contains('fox'); // false

1
2
3
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

array.prototype.some()在第5版中添加到ECMA-262标准中


一种有望更快的双向indexOf/lastIndexOf替代方案

二千零一十五

虽然新方法包括非常好的,但目前支持基本为零。

很长一段时间以来,我一直在思考如何替换慢速indexof/lastindexof函数。

我们已经找到了一种有效的方法,看看最重要的答案。从这些文章中,我选择了@damir zekic发布的contains函数,它应该是最快的函数。但它也指出,基准是从2008年开始的,因此是过时的。

我也更喜欢while而不是for,但是由于没有特定的原因,我结束了用for循环编写函数。它也可以用一个while --来完成。

我很好奇,如果在执行该操作时检查数组的两边,迭代是否慢得多。显然不是,所以这个函数的速度大约是最高投票数的两倍。显然,它也比本地的快。在现实环境中,您永远不知道要搜索的值是在数组的开头还是结尾。

当你知道你只是用一个值推一个数组时,使用LastIndexOf可能仍然是最好的解决方案,但是如果你必须遍历大数组,结果可能无处不在,这可能是一个使事情更快的可靠解决方案。

双向索引/lastindexof

1
2
3
4
5
6
7
8
9
10
function bidirectionalIndexOf(a, b, c, d, e){
  for(c=a.length,d=c*1; c--; ){
    if(a[c]==b) return c; //or this[c]===b
    if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
  }
  return -1
}

//Usage
bidirectionalIndexOf(array,'value');

性能试验

http://jspef.com/bidirectionalindexof

作为测试,我创建了一个包含100K条目的数组。

三个查询:在数组的开头、中间和结尾。

我希望你也能发现这一点,并测试一下性能。

注:如您所见,我略微修改了contains函数,以反映输出的&lastindex的索引(基本上是trueindexfalse-1的索引)。那不应该伤害它。

阵列原型变量

1
2
3
4
5
6
7
8
9
10
Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
  for(c=this.length,d=c*1; c--; ){
    if(this[c]==b) return c; //or this[c]===b
    if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
  }
  return -1
},writable:false, enumerable:false});

// Usage
array.bidirectionalIndexOf('value');

函数也可以很容易地修改为返回true或false,甚至返回对象、字符串或任何它是什么。

这里是while变体:

1
2
3
4
5
6
7
8
9
10
11
function bidirectionalIndexOf(a, b, c, d){
  c=a.length; d=c-1;
  while(c--){
    if(b===a[c]) return c;
    if(b===a[d-c]) return d-c;
  }
  return c
}

// Usage
bidirectionalIndexOf(array,'value');

这怎么可能?

我认为得到数组中反射索引的简单计算非常简单,比实际循环迭代快两倍。

这里有一个复杂的例子,每次迭代都要进行三次检查,但这只能在计算时间较长的情况下进行,这会导致代码的速度减慢。

http://jspef.com/bidirectionalindexof/2


我们使用此代码段(用于对象、数组、字符串):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * @function
 * @name Object.prototype.inArray
 * @description Extend Object prototype within inArray function
 *
 * @param {mix}    needle       - Search-able needle
 * @param {bool}   searchInKey  - Search needle in keys?
 *
 */

Object.defineProperty(Object.prototype, 'inArray',{
    value: function(needle, searchInKey){

        var object = this;

        if( Object.prototype.toString.call(needle) === '[object Object]' ||
            Object.prototype.toString.call(needle) === '[object Array]'){
            needle = JSON.stringify(needle);
        }

        return Object.keys(object).some(function(key){

            var value = object[key];

            if( Object.prototype.toString.call(value) === '[object Object]' ||
                Object.prototype.toString.call(value) === '[object Array]'){
                value = JSON.stringify(value);
            }

            if(searchInKey){
                if(value === needle || key === needle){
                return true;
                }
            }else{
                if(value === needle){
                    return true;
                }
            }
        });
    },
    writable: true,
    configurable: true,
    enumerable: false
});

用途:

1
2
3
4
5
6
7
8
9
10
var a = {one:"first", two:"second", foo: {three:"third
<div class="
suo-content">[collapse title=""]<ul><li>我就把它放在这里。</li></ul>[/collapse]</div><hr>[cc lang="javascript"]function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
}

如果找到则返回数组索引,如果找不到则返回-1


如果您使用的是javascript 1.6或更高版本(firefox 1.5或更高版本),则可以使用array.indexof。否则,我认为您最终会得到与原始代码类似的代码。


如果您反复检查数组中是否存在某个对象,您可能应该查看

  • 通过在数组中执行插入排序,使数组始终保持排序(将新对象放在正确的位置)
  • 将更新对象设置为删除+排序的插入操作和
  • 在您的contains(a, obj)中使用二进制搜索查找。

  • 适用于所有现代浏览器的解决方案:

    1
    2
    3
    4
    function contains(arr, obj) {
      const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
      return arr.some(item => JSON.stringify(item) === stringifiedObj);
    }

    用途:

    1
    contains([{a: 1}, {a: 2}], {a: 1}); // true

    IE6+解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function contains(arr, obj) {
      var stringifiedObj = JSON.stringify(obj)
      return arr.some(function (item) {
        return JSON.stringify(item) === stringifiedObj;
      });
    }

    // .some polyfill, not needed for IE9+
    if (!('some' in Array.prototype)) {
      Array.prototype.some = function (tester, that /*opt*/) {
        for (var i = 0, n = this.length; i < n; i++) {
          if (i in this && tester.call(that, this[i], i, this)) return true;
        } return false;
      };
    }

    用途:

    1
    contains([{a: 1}, {a: 2}], {a: 1}); // true

    为什么要使用JSON.stringify

    Array.indexOfArray.includes(以及这里的大多数答案)仅通过参考而不是价值进行比较。

    1
    2
    [{a: 1}, {a: 2}].includes({a: 1});
    // false, because {a: 1} is a new object

    奖金

    非优化ES6一衬板:

    1
    2
    [{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
    // true

    注:如果键的顺序相同,则按值比较对象会更好,因此为了安全起见,您可以首先使用类似这样的包对键进行排序:https://www.npmjs.com/package/sort-keys

    通过性能优化更新了contains函数。感谢您的行程安排。


    使用罗达什的一些功能。

    它简洁、准确,具有很好的跨平台支持。

    接受的答案甚至不符合要求。

    要求:推荐最简洁和有效的方法来确定JavaScript数组是否包含对象。

    接受的答案:

    1
    2
    $.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
    > -1

    我的建议:

    1
    2
    _.some([{'a': 1}, {'b': 2}], {'b': 2})
    > true

    笔记:

    .in array可以很好地确定标量数组中是否存在标量值…

    1
    2
    $.inArray(2, [1,2])
    > 1

    …但这个问题显然需要一种有效的方法来确定对象是否包含在数组中。

    为了同时处理scalar和对象,可以这样做:

    1
    (_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

    虽然array.indexOf(x)!=-1是实现这一点的最简洁的方法(并且已经被非Internet Explorer浏览器支持了十多年…),但它不是o(1),而是o(n),这很糟糕。如果数组不变,可以将数组转换为哈希表,然后执行table[x]!==undefined===undefined操作:

    1
    2
    3
    4
    5
    Array.prototype.toTable = function() {
        var t = {};
        this.forEach(function(x){t[x]=true});
        return t;
    }

    演示:

    1
    2
    var toRemove = [2,4].toTable();
    [1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

    (不幸的是,虽然您可以创建array.prototype.contains来"冻结"数组并在此中存储哈希表。_缓存为两行,但如果您以后选择编辑数组,这将产生错误的结果。JavaScript没有足够的钩子来让您保持这种状态,例如,与Python不同。)


    ECMAScript 6有一个关于寻找的优雅建议。

    The find method executes the callback function once for each element
    present in the array until it finds one where callback returns a true
    value. If such an element is found, find immediately returns the value
    of that element. Otherwise, find returns undefined. callback is
    invoked only for indexes of the array which have assigned values; it
    is not invoked for indexes which have been deleted or which have never
    been assigned values.

    这是MDN文档。

    查找功能的工作方式如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function isPrime(element, index, array) {
        var start = 2;
        while (start <= Math.sqrt(element)) {
            if (element % start++ < 1) return false;
        }
        return (element > 1);
    }

    console.log( [4, 6, 8, 12].find(isPrime) ); // Undefined, not found
    console.log( [4, 5, 8, 12].find(isPrime) ); // 5

    通过定义函数,您可以在ECMAScript 5及以下版本中使用它。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    if (!Array.prototype.find) {
      Object.defineProperty(Array.prototype, 'find', {
        enumerable: false,
        configurable: true,
        writable: true,
        value: function(predicate) {
          if (this == null) {
            throw new TypeError('Array.prototype.find called on null or undefined');
          }
          if (typeof predicate !== 'function') {
            throw new TypeError('predicate must be a function');
          }
          var list = Object(this);
          var length = list.length >>> 0;
          var thisArg = arguments[1];
          var value;

          for (var i = 0; i < length; i++) {
            if (i in list) {
              value = list[i];
              if (predicate.call(thisArg, value, i, list)) {
                return value;
              }
            }
          }
          return undefined;
        }
      });
    }


    用途:

    1
    2
    3
    var myArray = ['yellow', 'orange', 'red'] ;

    alert(!!~myArray.indexOf('red')); //true

    演示

    为了准确知道tilde~在这一点上做了什么,请参考这个问题,当tilde在表达式之前做什么?.


    原型是这样做的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
     *  Array#indexOf(item[, offset = 0]) -> Number
     *  - item (?): A value that may or may not be in the array.
     *  - offset (Number): The number of initial items to skip before beginning the
     *      search.
     *
     *  Returns the position of the first occurrence of `item` within the array &mdash; or
     *  `-1` if `item` doesn't exist in the array.
    **/

    function indexOf(item, i) {
      i || (i = 0);
      var length = this.length;
      if (i < 0) i = length + i;
      for (; i < length; i++)
        if (this[i] === item) return i;
      return -1;
    }

    另请看这里了解它们是如何连接起来的。


    Use:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Array.prototype.contains = function(x){
      var retVal = -1;

      // x is a primitive type
      if(["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}

      // x is a function
      else if(typeof x =="function") for(var ix in this){
        if((this[ix]+"")==(x+"")) retVal = ix;
      }

      //x is an object...
      else {
        var sx=JSON.stringify(x);
        for(var ix in this){
          if(typeof this[ix] =="object" && JSON.stringify(this[ix])==sx) retVal = ix;
        }
      }

      //Return False if -1 else number if numeric otherwise string
      return (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);
    }

    我知道这不是最好的方法,但是由于没有本地的IComparable方法来在对象之间进行交互,我想这是比较数组中两个实体所能得到的最接近的方法。此外,扩展数组对象可能不是一件明智的事情,但有时它是可以的(如果您知道它和权衡)。


    可以使用具有方法"has()"的集合:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function contains(arr, obj) {
      var proxy = new Set(arr);
      if (proxy.has(obj))
        return true;
      else
        return false;
    }

    var arr = ['Happy', 'New', 'Year'];
    console.log(contains(arr, 'Happy'));


    你也可以使用这个技巧:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var arrayContains = function(object) {
      return (serverList.filter(function(currentObject) {
        if (currentObject === object) {
          return currentObject
        }
        else {
          return false;
        }
      }).length > 0) ? true : false
    }


    好吧,你可以优化你的代码来得到结果!

    有很多方法可以做到这一点,更干净更好,但我只是想得到您的模式,并应用到使用JSON.stringify的模式中,在您的情况下,只需这样做:

    1
    2
    3
    4
    5
    6
    7
    8
    function contains(a, obj) {
        for (var i = 0; i < a.length; i++) {
            if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
                return true;
            }
        }
        return false;
    }

  • 要么使用Array.indexOf(Object)
  • 使用ECMA 7,可以使用Array.includes(Object)
  • 使用ECMA 6,您可以使用Array.find(FunctionName),其中FunctionName是用户。定义了在数组中搜索对象的函数。

    希望这有帮助!


  • 正如其他人所提到的,您可以使用Array.indexOf,但并非所有浏览器都可以使用。这是来自https://developer.mozilla.org/en-us/docs/javascript/reference/global_objects/array/indexof的代码,可以使其在旧浏览器中工作相同。

    indexOf is a recent addition to the ECMA-262 standard; as such it may
    not be present in all browsers. You can work around this by inserting
    the following code at the beginning of your scripts, allowing use of
    indexOf in implementations which do not natively support it. This
    algorithm is exactly the one specified in ECMA-262, 5th edition,
    assuming Object, TypeError, Number, Math.floor, Math.abs, and Math.max
    have their original value.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
           "use strict";
            if (this == null) {
                throw new TypeError();
            }
            var t = Object(this);
            var len = t.length >>> 0;
            if (len === 0) {
                return -1;
            }
            var n = 0;
            if (arguments.length > 1) {
                n = Number(arguments[1]);
                if (n != n) { // shortcut for verifying if it's NaN
                    n = 0;
                } else if (n != 0 && n != Infinity && n != -Infinity) {
                    n = (n > 0 || -1) * Math.floor(Math.abs(n));
                }
            }
            if (n >= len) {
                return -1;
            }
            var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
            for (; k < len; k++) {
                if (k in t && t[k] === searchElement) {
                    return k;
                }
            }
            return -1;
        }
    }

    当然不是最好的,但我只是在创造和增加剧目。

    不要使用这个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Object.defineProperty(Array.prototype, 'exists', {
      value: function(element, index) {

        var index = index || 0

        return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
      }
    })


    // Outputs 1
    console.log(['one', 'two'].exists('two'));

    // Outputs -1
    console.log(['one', 'two'].exists('three'));

    console.log(['one', 'two', 'three', 'four'].exists('four'));


    如果您使用的是ES6,则可以使用集合:

    1
    2
    3
    4
    function arrayHas( array, element ) {
        const s = new Set(array);
        return s.has(element)
    }

    这应该比任何其他方法都更具性能。


    我建议使用下划线库,因为它返回值并支持所有浏览器。

    弱智者

    1
    2
    3
     var findValue = _.find(array, function(item) {
        return item.id == obj.id;
     });

    它有一个参数:对象数组。数组中的每个对象都有两个整数属性,用x和y表示。函数必须返回数组中满足numbers.x == numbers.y的所有这些对象的计数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var numbers = [ { x: 1, y: 1 },
                     { x: 2, y: 3 },
                     { x: 3, y: 3 },
                     { x: 3, y: 4 },
                     { x: 4, y: 5 } ];
        count = 0;
    var n = numbers.length;
    for (var i =0;i<n;i++)
    {
      if(numbers[i].x==numbers[i].y)
      {count+=1;}
    }

    alert(count);


    我查看了提交的答案,发现它们只适用于通过引用搜索对象的情况。一个简单的线性搜索与参考对象比较。

    但是假设您没有对象的引用,那么如何在数组中找到正确的对象呢?与每个对象进行线性和深度比较。想象一下,如果列表太大,其中的对象非常大,其中包含大量文本。随着数组中元素的数量和大小,性能急剧下降。

    您可以将对象串起来并将其放入本机哈希表中,但随后您将有数据冗余,记住这些键,因为JavaScript将它们保留为"for i in obj",并且您只想检查对象是否存在,也就是说,您是否拥有该键。

    我考虑了一段时间,构建了一个JSON模式验证器,并为本机哈希表设计了一个简单的包装器,类似于唯一的哈希表实现,还有一些优化异常,这些优化异常是我留给本机哈希表处理的。它只需要性能基准…所有的细节和代码都可以在我的博客上找到:http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/我将很快公布基准结果。

    完整的解决方案如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    var a = {'a':1,
     'b':{'c':[1,2,[3,45],4,5],
     'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
     'u':'lol'},
     'e':2};

     var b = {'a':1,
     'b':{'c':[2,3,[1]],
     'd':{'q':3,'b':{'b':3}}},
     'e':2};

     var c ="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

     var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

     hc.put({a:1, b:1});
     hc.put({b:1, a:1});
     hc.put(true);
     hc.put('true');
     hc.put(a);
     hc.put(c);
     hc.put(d);
     console.log(hc.exists('true'));
     console.log(hc.exists(a));
     console.log(hc.exists(c));
     console.log(hc.exists({b:1, a:1}));
     hc.remove(a);
     console.log(hc.exists(c));

    或者这个解决方案:

    1
    2
    3
    Array.prototype.includes = function (object) {
      return !!+~this.indexOf(object);
    };

    我正在做一个项目,我需要一个像python set这样的功能,它删除所有重复的值并返回一个新的列表,所以我编写了这个函数,可能对某些人有用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function set(arr) {
        var res = [];
        for (var i = 0; i < arr.length; i++) {
            if (res.indexOf(arr[i]) === -1) {
                res.push(arr[i]);
            }
        }
        return res;
    }

    类似的事情:通过"搜索lambda"查找第一个元素:

    1
    2
    3
    Array.prototype.find = function(search_lambda) {
      return this[this.map(search_lambda).indexOf(true)];
    };

    用途:

    1
    2
    [1,3,4,5,8,3,5].find(function(item) { return item % 2 == 0 })
    => 4

    咖啡中的描述相同:

    1
    Array.prototype.find = (search_lambda) -> @[@map(search_lambda).indexOf(true)]


    令人惊讶的是,这个问题仍然没有添加最新的语法,增加了我的2美分。

    假设我们有一个对象数组arrobj,我们想在其中搜索obj。

    array.prototype.index of->(返回index或-1)通常用于查找数组中元素的索引。这也可用于搜索对象,但仅在传递对同一对象的引用时才有效。

    1
    2
    3
    4
    5
    6
    7
    8
    let obj = { name: 'Sumer', age: 36 };
    let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];


    console.log(arrObj.indexOf(obj));// 0
    console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1

    console.log([1, 3, 5, 2].indexOf(2)); //3

    array.prototype.includes->(返回true或false)

    1
    2
    3
    4
    console.log(arrObj.includes(obj));  //true
    console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

    console.log([1, 3, 5, 2].includes(2)); //true

    array.prototype.find->(接受回调,返回cb中返回true的第一个值/对象)。

    1
    2
    3
    4
    console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }
    console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }

    console.log([1, 3, 5, 2].find(e => e > 2)); //3

    array.prototype.findindex->(接受回调,返回cb中返回true的第一个值/对象的索引)。

    1
    2
    3
    4
    console.log(arrObj.findIndex(e => e.age > 40));  //1
    console.log(arrObj.findIndex(e => e.age > 40)); //1

    console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

    由于find和findindex接受回调,因此可以通过创造性地设置true条件从数组中获取任何对象(即使我们没有引用)。


    使用idnexof()是一个很好的解决方案,但是您应该隐藏内嵌的实现indexof()函数,该函数返回-1和~operator:

    1
    2
    3
    function include(arr,obj) {
        return !!(~arr.indexOf(obj));
    }

    Simple solution : ES6 Features "includes" method

    1
    2
    3
    4
    5
    let arr = [1, 2, 3, 2, 3, 2, 3, 4];

      arr.includes(2) // true

      arr.includes(93) // false

    除了其他人所说的,如果您没有要在数组中搜索的对象的引用,那么您可以这样做。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    let array = [1, 2, 3, 4, {"key":"value
    <hr>
    [cc lang="
    javascript"]function countArray(originalArray) {

        var compressed = [];
        // make a copy of the input array
        var copyArray = originalArray.slice(0);

        // first loop goes over every element
        for (var i = 0; i < originalArray.length; i++) {

            var count = 0;  
            // loop over every element in the copy and see if it's the same
            for (var w = 0; w < copyArray.length; w++) {
                if (originalArray[i] == copyArray[w]) {
                    // increase amount of times duplicate is found
                    count++;
                    // sets item to undefined
                    delete copyArray[w];
                }
            }

            if (count > 0) {
                var a = new Object();
                a.value = originalArray[i];
                a.count = count;
                compressed.push(a);
            }
        }

        return compressed;
    };

    // It should go something like this:

    var testArray = new Array("
    dog","dog","cat","buffalo","wolf","cat","tiger","cat");
    var newArray = countArray(testArray);
    console.log(newArray);

    在构建函数中使用include javascript

    1
    2
    3
    4
    5
    var optval = [];

    optval.push('A');    
    optval.push('B');    
    optval.push('C');

    我们可以在javascript数组中搜索字符串a,如下所示:

    1
    optval.includes('A') // =====> return true


    字面上的:

    (使用火狐3.6版,有for-in警告,如前所述)(不过,下面的使用可能会为此目的支持for-in!也就是说,枚举通过属性索引实际存在的数组元素(但是,尤其是数组length属性没有在for-in属性列表中枚举!))

    (拖放以下完整的URI以进行即时模式浏览器测试。)

    JavaScript:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      function ObjInRA(ra){var has=false; for(i in ra){has=true; break;} return has;}

      function check(ra){
          return ['There is ',ObjInRA(ra)?'an':'NO',' object in [',ra,'].'].join('')
      }
      alert([
                check([{}]), check([]), check([,2,3]),
                check(['']), '\t (a null string)', check([,,,])
            ].join('
    '
    ));

    显示:

    1
    2
    3
    4
    5
    6
    There is an object in [[object Object]].
    There is NO object in [].
    There is an object in [,2,3].
    There is an object in [].
         (a null string)
    There is NO object in [,,].

    皱纹:如果要查找"特定"对象,请考虑:

    javascript:alert({}!={}); alert({}!=={});

    因此:

    JavaScript:

    1
    2
    3
    4
    5
    6
    7
     obj = {prop:"value
    <hr><P>只是另一个选择</P>[cc lang="
    javascript"]// usage: if ( ['a','b','c','d'].contains('b') ) { ... }
    Array.prototype.contains = function(value){
        for (var key in this)
            if (this[key] === value) return true;
        return false;
    }

    请小心,因为使用自定义方法重载JavaScript数组对象会破坏其他JavaScript的行为,从而导致意外的行为。