简体   繁体   English

如何找到集合中数组的存在?

[英]How to find existence of an array in a set?

Since set in Javascript is able to take object, including arrays, how do I find the existence of an array list in a set? 由于使用Javascript设置的集合能够获取包括数组在内的对象,因此如何找到集合中数组列表的存在?

I tried the following code: 我尝试了以下代码:

var sello = new Set();
sello.add(["a","b"])
console.log(sello.has(["a","b"])) // outputs false

I'm assuming 我假设

sello.has(["a","b"])

should have output true since I've added the exact array in the set sello . 因为我已经在set sello添加了确切的数组,所以应该输出true。 Am I missing out some falsy truthy thing or any logical error? 我是否错过了一些虚假的真实事物或任何逻辑错误?

Note: 注意:

  • I'm not looking to match only the character "a" and/or "b" , I'm looking to match the whole array ["a","b"] . 我不希望仅匹配字符"a"和/或"b" ,而是希望匹配整个数组["a","b"]

  • I'm looking to match the array. 我正在寻找匹配数组。 I just need the content to be the 我只需要内容是
    same, the elements doesn't have to be the same order. 相同,元素不必具有相同的顺序。

What you're trying to do won't work because in Javascript you can't compare arrays like that, even if they have the same values. 您尝试执行的操作将不起作用,因为在Javascript中,即使它们具有相同的值,也无法像这样比较数组。 This is because arrays are reference types, not value types, and for reference types Javascript determines whether they are equal or not based on whether they are referencing the same object (ie the same place in memory). 这是因为数组是引用类型,而不是值类型,并且对于引用类型,Javascript根据它们是否引用相同的对象(即内存中的相同位置)来确定它们是否相等。 For instance, just try: 例如,只需尝试:

console.log(['a','b'] == ['a','b']); // false

Despite having the same values, each array is a new reference, so they are not equal to each other. 尽管具有相同的值,但每个数组都是新的引用,因此它们彼此不相等。

In contrast, the comparison in the code below does involve arrays referencing the same object on both sides of the equation: 相反,以下代码中的比较确实涉及在等式两边都引用相同对象的数组:

let a = ['a','b'];
console.log(a == a); // true

And therefore: 因此:

let sello = new Set();
sello.add(a);
console.log(sello.has(a)); // true

To remedy this, you'll want to create a function that compares arrays based on their values. 为了解决这个问题,您将需要创建一个根据数组值比较数组的函数。 You can first check if the arrays have the same length. 您可以先检查数组的长度是否相同。 If not, then they're not equal. 如果不是,则它们不相等。 You can then loop through the items in each and see if any are different for any given position. 然后,您可以遍历每个项目中的项目,并查看任何给定位置的项目是否不同。 If so, they're not equal. 如果是这样,它们是不相等的。 Otherwise, assuming you're dealing with a flat array of primitive values (no nested objects of reference type), then the arrays are equal. 否则,假设您要处理的是原始值的平面数组(没有引用类型的嵌套对象),则数组相等。 This is what I do in 'isEqual' below: 这是我在下面的“ isEqual”中所做的:

function isEqual(x,y) {
    if (x.length != y.length)
        return false;
    for (let i in x)
        if (x[i] != y[i])
            return false;
    return true;
}

Test it if you like: 如果您愿意,请对其进行测试:

console.log(isEqual(['a','b'],['a','b'])); // true

Now, unfortunately, Set.has() doesn't accept a function, so we can't use it with isEqual . 现在,不幸的是, Set.has()不接受函数,因此我们不能将其与isEqual一起使用。 But you can just loop through the values of the set. 但是,您可以遍历集合的值。 If creating a one-liner is the goal, the best way I have found to do this is to convert the set to an array and use the some method. 如果创建单行是目标,那么我发现做到这一点的最佳方法是将集合转换为数组并使用some方法。 some accepts a function that evaluates each row, and if it returns true for any row, then the result is true, else false. some接受一个对每一行求值的函数,如果它对任何一行返回true,则结果为true,否则为false。

console.log(
    [...sello].some(item => isEqual(item, ['a','b']))
); 
// true

In JavaScript, Arrays are Objects, and no two separate Objects are ever considered equal. 在JavaScript中,数组是对象,没有两个单独的对象被视为相等。

MDN shows the same error with a standard object: MDN对标准对象显示相同的错误:

var set1 = new Set();
var obj1 = {'key1': 1};
set1.add(obj1);

set1.has(obj1);        // returns true
set1.has({'key1': 1}); // returns false because they are different object references


The easiest way to use .has with an Object (such as an Array) is to get a reference to the Object, like: 与对象一起使用.has的最简单方法是获取对对象的引用 ,例如:

 let sello = new Set(); let myArray = ["a","b"]; sello.add(myArray); console.log(sello.has(myArray)); // outputs true 


If you can't get a reference to the Array, you'll probably need to check each Array in the Set by iterating through the Array and comparing each element individually. 如果无法获得对数组的引用,则可能需要通过遍历数组并分别比较每个元素来检查Set中的每个数组。

You could do this more concisely, but this explicit example clarifies the process: 您可以更简洁地执行此操作,但是此显式示例阐明了该过程:

 // Declares and populates the Set let sello = new Set(); sello.add( ["a", "c"] ); sello.add( ["a", "b"] ); sello.add( ["b", "c"] ); // Tests the `setHasArray` function let result = setHasArray(sello, ["a", "b"]); console.log(`result: ${result}`); // Defines the `setHasArray` function function setHasArray(theSet, arrayToMatch){ // Creates a flag let isMatch = false; // Iterates through the Set for (let member of theSet){ // Logs the Array we're about to compare elements of console.log("comparing:", member); // Makes sure this member is an Array before proceeding if(Array.isArray(member)){ // Tentatively sets the flag to `true` isMatch = true; // Iterates through the Array, comparing each value arrayToMatch.forEach( (_, index) => { // Logs the comparison for the current value console.log( member[index] + (member[index] === arrayToMatch[index] ? " === " : " !== ") + arrayToMatch[index] ); // Even one non-matching element means the Array doesn't match if(member[index] !== arrayToMatch[index]){ console.log("Rats! Looked like a possible match there for a second."); isMatch = false; } }); // Logs a successful match for the current member of the Set if(isMatch){ console.log("Found a match!") // Stops checking Arrays lest the flag get reset and give us a false negative break; } } } // Returns our result return isMatch; } 

(See .forEach on MDN if you're not familiar with this method.) (如果您不熟悉此方法,请参阅MDN上的.forEach 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM