¿Cómo se comparan dos conjuntos de JavaScript? Intenté usar ==
y, ===
pero ambos devuelven falso.
a = new Set([1,2,3]);
b = new Set([1,3,2]);
a == b; //=> false
a === b; //=> false
Estos dos conjuntos son equivalentes porque, por definición, los conjuntos no tienen orden (al menos no habitualmente). Revisé la documentación de Set on MDN y no encontré nada útil. Alguien sabe cómo hacer esto?
javascript
set
ecmascript-6
williamcodes
fuente
fuente
===
es para igualdad de valor, no igualdad de objeto.new Set([1,2,3]) != new Set([1,2,3])
. Esto hace que Javascript Set sea inútil para conjuntos de conjuntos porque el superconjunto contendrá subconjuntos duplicados. La única solución alternativa que viene a la mente es convertir todos los subconjuntos en matrices, ordenar cada matriz y luego codificar cada matriz como una cadena (por ejemplo, JSON).Respuestas:
Prueba esto:
Un enfoque más funcional sería:
La
all
función funciona para todos los objetos iterables (por ejemplo,Set
yMap
).Si
Array.from
tuviera un apoyo más amplio, podríamos haber implementado laall
función como:Espero que ayude.
fuente
has
aisPartOf
oisIn
oelem
has
aisIn
.También puedes probar:
fuente
lodash proporciona
_.isEqual()
, que hace comparaciones profundas. Esto es muy útil si no quieres escribir el tuyo propio. A partir de lodash 4,_.isEqual()
compara correctamente Sets.fuente
La otra respuesta funcionará bien; aquí hay otra alternativa.
Sin embargo, tenga en cuenta que esto no hace una comparación de igualdad profunda. Entonces
devolverá falso. Si los dos conjuntos anteriores deben considerarse iguales, debemos recorrer ambos conjuntos haciendo comparaciones profundas de calidad en cada elemento. Estipulamos la existencia de una
deepEqual
rutina. Entonces la lógica seríaQué hace esto: para cada miembro de s1, busque un miembro profundamente igual de s2. Si lo encuentra, elimínelo para que no se pueda volver a utilizar. Los dos conjuntos son profundamente iguales si todos los elementos de s1 se encuentran en s2 y s2 se agota. No probado.
Puede encontrar esto útil: http://www.2ality.com/2015/01/es6-set-operations.html .
fuente
Ninguna de estas soluciones "devuelve" la funcionalidad esperada a una estructura de datos como un conjunto de conjuntos. En su estado actual, el conjunto de Javascript es inútil para este propósito porque el superconjunto contendrá subconjuntos duplicados, que Javascript ve erróneamente como distintos. La única solución en la que puedo pensar es convertir cada subconjunto a Array , ordenarlo y luego codificarlo como String (por ejemplo, JSON).
Solución
Uso básico
Prueba definitiva: conjunto de conjuntos
fuente
[...set1].sort().toString() === [...set2].sort().toString()
La razón por la que su enfoque devuelve falso es porque está comparando dos objetos diferentes (incluso si tienen el mismo contenido), por lo que comparar dos objetos diferentes (no referencias, sino objetos) siempre devuelve falso.
El siguiente enfoque fusiona dos conjuntos en uno y simplemente compara estúpidamente el tamaño. Si es lo mismo, es lo mismo:
Al revés : es muy simple y corto. Sin biblioteca externa solo vanilla JS
Desventaja : Probablemente será más lento que simplemente iterar sobre los valores y necesitará más espacio.
fuente
Comparando dos objetos con ==, ===
Cuando use el operador
==
u===
para comparar dos objetos, siempre obtendrá afalse
menos que esos objetos hagan referencia al mismo objeto . Por ejemplo:De lo contrario, == equivale a falso aunque el objeto contenga los mismos valores:
Es posible que deba considerar la comparación manual
En ECMAScript 6, puede convertir conjuntos en matrices de antemano para que pueda detectar la diferencia entre ellos:
NOTA:
Array.from
es una de las características estándar de ECMAScript 6 pero no es ampliamente compatible con los navegadores modernos. Consulte la tabla de compatibilidad aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibilityfuente
b
que no estána
?b
no están incluidosa
es comprobar sia.size === b.size
.a.size === b.size
primero en cortocircuito la comparación de elementos individuales si no es necesario?has
operación en conjuntos está diseñada para ser muy eficiente, a diferencia de laindexOf
operación en matrices. Por lo tanto, tendría sentido cambiar la función de filtro para que seareturn !b.has(i)
. Eso también eliminaría la necesidad de convertirb
en una matriz.Creé un polyfill rápido para Set.prototype.isEqual ()
Github Gist - Set.prototype.isEqual
fuente
Según la respuesta aceptada, asumiendo el apoyo de
Array.from
, aquí hay una frase:fuente
eqSet = (a,b) => a.size === b.size && [...a].every(b.has.bind(b))
Si los conjuntos contienen solo tipos de datos primitivos o los objetos dentro de los conjuntos tienen igualdad de referencia, entonces hay una forma más sencilla
const isEqualSets = (set1, set2) => (set1.size === set2.size) && (set1.size === new Set([...set1, ...set2]).size);
fuente
Sigo este enfoque en las pruebas:
fuente
a=[1,2,3]
yb=[1,2,3,4]
, entonces dice que son lo mismo. Así que supongo que necesita un cheque adicional comosetA.size === setB.size
Modificación muy leve basada en la respuesta de @Aadit M Shah:
Si alguien más tiene un problema como yo debido a alguna peculiaridad del último babel, tenía que agregar un condicional explícito aquí.
(También para el plural, creo que
are
es un poco más intuitivo de leer en voz alta)fuente
1) Compruebe si los tamaños son iguales. Si no, entonces no son iguales.
2) iterar sobre cada elemento de A y verificar que exista en B. Si uno falla, regrese
unequal
3) Si las 2 condiciones anteriores fallan, significa que son iguales.
2) Método 2
fuente
forEach
método NO hará que la función principal regrese.