Tengo un caso de uso simple que solía funcionar en mi código, sin embargo, ahora tuve que hacer cambios para solucionar un problema que ahora tengo. Buscando obtener algunas ideas sobre por qué esto ha cambiado y requiere una verificación adicional si alguien puede ayudar. Mi escenario es como se describe.
Tengo una matriz userBadgeIds
que contiene lo siguiente: [ new ObjectId("59f347fca0f50c0004b5a3ac") ]
Solía hacer la siguiente línea: const exists = userBadgeIds.includes(badge._id)
que funcionó perfectamente y me dijo si la entrada badge._id
estaba en la matriz. Ambos son ObjectId
de mongoose, por lo que comparar equivalentes de esta manera parecía perfecto (¡nuevamente, funcionó!).
Sin embargo, por la razón que sea, ahora tengo que compararlos de la siguiente manera:
const exists = userBadgeIds.map(String).includes(badge._id.toString())
Ahora funciona de nuevo. ¿Hay algo que me falta sobre cómo .includes
compara la equivalencia o algo que me falta sobre la comparación de ObjectId
específicamente con ObjectId[]
?
Cuando comparas objetos, tienen que ser exactamente el mismo objeto y no un objeto que tenga las mismas propiedades.
Es posible que algo haya cambiado en su código en otro lugar o en una biblioteca que convierte lo que era básicamente esto:
const obj1 = { _id: 'a' }; const obj2 = { _id: 'b' }; const obj3 = { _id: 'c' }; const searchFor = obj1; [obj1, obj2, obj3].includes(searchFor); // true
En algo que es esencialmente esto:
const obj1 = { _id: 'a' }; const obj2 = { _id: 'b' }; const obj3 = { _id: 'c' }; const searchFor = { _id: 'a' }; [obj1, obj2, obj3].includes(searchFor); // false
searchFor
puede tener las mismas propiedades y prototipo, pero no es exactamente el mismo objeto que obj1
. Tal vez algún código esté clonando badge
, por lo que no es igual a las entradas en la matriz userBadgeIds
.
Su solución funciona, porque cuando compara cadenas, no tienen que ser exactamente la misma cadena, solo tienen el mismo valor .
Aparte, hay ObjectId.prototype.equals()
para comparar dos ObjectIds (idénticos o equivalentes).
// You need to pass searchFor as the second parameter to `some` // so that `this` is correctly set. [obj1, obj2, obj3].some(searchFor.equals, searchFor); // Or you can do: [obj1, obj2, obj3].some(searchFor.equals.bind(searchFor)); // Or: [obj1, obj2, obj3].some(id => searchFor.equals(id));
Array.prototype.some
devuelve true
si alguna entrada de la matriz coincide con la función de devolución de llamada, como lo hace includes
para los valores.