【问题标题】:check if an array "includes" an item in Javascript检查数组是否“包含”Javascript中的项目
【发布时间】:2019-08-20 05:56:32
【问题描述】:

我试图理解数组“包含”函数。我的目标是确定一个数组是否包含某个项目。它适用于字符串数组,但在使用对象时它不起作用。

    var itemsString = ["name1", "name2"];
    var itemsObject = [{ name: "name1" }, { name: "name2" }];
    var itemToSearch = { name: "name1" };
    
    console.log(itemsString.includes("name1" ));
    console.log(itemsObject.includes(itemToSearch));
    console.log(itemsObject.includes(x => x.name === "name1"));

输出:

  • 是的

“包含”是否适用于对象,还是我需要使用其他函数?

【问题讨论】:

  • [{ name: "name1" }, { name: "name2" }]; 索引 0 处的项目实际上与 var itemToSearch = { name: "name1" }; 不同,因为它们是不同的对象。尽管两个对象具有相同的属性,但它们是不同的实例,因此它们具有不同的引用,因此它们并不相同。但是,如果您对它们进行字符串化,在这种情况下它们将是相同的。
  • 只是为了消除混淆Array#includes 使用对象的方式与所有对象比较的工作方式相同 - 只有当它字面上是相同的对象实例时才会找到条目,而不是如果这是一个看起来很相似的对象。
  • itemsObject.some(x => x.name === "name1")
  • @giorgim 谢谢,重新考虑
  • 你最后一次尝试的方向是正确的,只是使用的方法不是.include()而是.some()

标签: javascript


【解决方案1】:

在这种情况下,您需要使用Array.prototype.some()Array.prototype.includes() 不接受函数参数*,并且您没有测试严格相等。

const itemsObject = [{ name: "name1" }, { name: "name2" }];

console.log(itemsObject.some(x => x.name === "name1"));

*来自 cmets 部分的同行压力迫使我澄清includes() 确实接受函数参数,但不会使用传递的函数作为谓词来确定给定项目是否匹配。相反,它将尝试在数组中找到与传递的函数严格相等的项。

【讨论】:

  • 不接受函数参数”它接受函数参数。如果没有,它会抛出一个错误。发生的情况是该函数未执行,而是针对数组进行检查。该数组的任何对象都不是函数本身,因此,它返回false
  • @VLAZ 好的,我的措辞有些不正确。我的意思是:不接受将用作谓词来确定给定数组项是否匹配的函数参数。
  • 那么请相应地调整你的答案。
【解决方案2】:

“包含”是否适用于对象或者我是否需要使用其他对象 功能?

包括 works 与对象,但它通过 reference 比较对象。 在您的情况下,尽管 itemsObject 的第一个元素具有与 itemToSearch 相同的键和值,但它们是不同的对象,因此 includes 将不起作用,因为,对于对象情况,它会查找相同的对象实例

为了使其正常工作,您可以使用多种替代方法,例如 .find.some.filter

另一个我个人不推荐但我认为值得一提的解决方案是,如果您首先将项目映射到字符串,则可以使用.includes。在这种情况下,使用 JSON.stringify,您可以检查对象是否相同。 注意:这仅适用于单键项目。 JSON.stringify 不保留键和值的顺序,因此它仅适用于单个键对象(除非键和值在原始字符串化对象中的顺序相同)。此外,JSON.stringify 方式比其他方式更重且性能更低,我只是认为值得一提的是,作为一个例子。

下面是他们每个人的一些例子。

var itemsString = ["name1", "name2"];
    var itemsObject = [{ name: "name1" }, { name: "name2" }];
    var itemToSearch = { name: "name1" };
    
    console.log(itemsObject.some(r => r.name === itemToSearch.name));
    console.log(!!itemsObject.find(r => r.name === itemToSearch.name));
    //          ^--- !! is used to cast to boolean.
    console.log(itemsObject.filter(r => r.name === itemToSearch.name).length > 0);
    console.log(itemsObject.map(i => JSON.stringify(i)).includes(JSON.stringify(itemToSearch)));
    //          ^--------------^                       ^---------------------------------------^
    //            |------ this will stringify each object, converting it to a json string.  |
    //                                                                                      |
    //                this will check whether the string[] includes any stringified value.--^

【讨论】:

    【解决方案3】:

    在最后一行中,您检查一个函数是否在您的数组中。 .includes 也适用于对象,但它通过引用比较它们。在您的情况下,您可能想要.find 或检查对象中的.some 是否与您的查询匹配。

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 2021-09-10
      相关资源
      最近更新 更多