En Eloquent JavaScript, Capítulo 4, se crea un conjunto de valores creando un objeto y almacenando los valores como nombres de propiedad, asignando valores arbitrarios (por ejemplo, verdadero) como valores de propiedad. Para comprobar si el valor ya está contenido en el conjunto, in
se utiliza el operador:
var set = {};
if (!'Tom' in set) {
set.Tom = true;
}
¿Es este JavaScript idiomático? ¿No estaría usando una matriz aún mejor?
var set = [];
if (!'Tom' in set) {
set.push = 'Tom';
}
javascript
set
método de ayuda
fuente
fuente
'Tom' in set
se vea una matriz para la que es verdadero? Parece que tienes suposiciones erróneas sobre algo y estoy tratando de averiguar qué .if(!('Tom' in set))
. Actualmente significafalse in set
desde!'Tom' === false
.Respuestas:
Los conjuntos ahora están disponibles en ES2015 (también conocido como ES6, es decir, ECMAScript 6). ES6 ha sido el estándar actual para JavaScript desde junio de 2015.
Los primeros dos ejemplos del libro de Axel Rauschmayer Exploring ES6 :
> let set = new Set(); > set.add('red') > set.has('red') true > set.delete('red') true > set.has('red') false
> let set = new Set(); > set.add('red') > set.add('green') > set.size 2 > set.clear(); > set.size 0
Me volvería a la salida Explorando ES6 si desea obtener más información acerca de los conjuntos de JavaScript. El libro es de lectura gratuita en línea, pero si desea apoyar al autor, el Dr. Axel Rauschmayer , puede comprarlo por alrededor de $ 30.
Si desea utilizar Sets y ES6 ahora, puede utilizar Babel , el transpilador de ES6 a ES5 y sus polyfills.
Editar: A partir del 6 de junio de 2017, la mayoría de los principales navegadores tienen soporte completo de Set en sus últimas versiones (excepto IE 11). Esto significa que es posible que no necesite babel si no le interesa admitir navegadores antiguos. Si desea ver la compatibilidad en diferentes navegadores, incluido su navegador actual, consulte la tabla de compatibilidad ES6 de Kangax .
EDITAR:
Solo una aclaración sobre la inicialización. Los conjuntos pueden tomar cualquier iterable sincrónico en su constructor. Esto significa que pueden tomar no solo matrices, sino también cadenas e iteradores. Tomemos, por ejemplo, la siguiente inicialización de matriz y cadena de un conjunto:
const set1 = new Set(['a','a','b','b','c','c']); console.log(...set1); console.log(set1.size); const set2 = new Set("aabbcc"); console.log(...set2); console.log(set2.size);
Ambas salidas de la matriz y la cadena son iguales. Tenga en cuenta que
...set1
es la sintaxis de propagación . Parece que cada elemento del iterable se agrega uno por uno al conjunto, por lo que, dado que tanto la matriz como la cadena tienen los mismos elementos y como los elementos están en el mismo orden, el conjunto se crea igual. Otra cosa a tener en cuenta sobre los conjuntos es que cuando se itera sobre ellos, el orden de iteración sigue el orden en que los elementos se insertaron en el conjunto. A continuación, se muestra un ejemplo de iteración sobre un conjunto:const set1 = new Set(['a','a','b','b','c','c']); for(const element of set1) { console.log(element); }
Dado que puede usar cualquier iterable para inicializar un conjunto, incluso podría usar un iterador de una función generadora . Aquí hay dos ejemplos de inicializaciones de iteradores que producen el mismo resultado:
// a simple generator example function* getLetters1 () { yield 'a'; yield 'a'; yield 'b'; yield 'b'; yield 'c'; yield 'c'; } // a somewhat more commonplace generator example // with the same output as getLetters1. function* getLetters2 (letters, repeatTimes) { for(const letter of letters) { for(let i = 0; i < repeatTimes; ++i) { yield letter; } } } console.log("------ getLetters1 ------"); console.log(...getLetters1()); const set3 = new Set(getLetters1()); console.log(...set3); console.log(set3.size); console.log("------ getLetters2 ------"); console.log(...getLetters2('abc', 2)); const set4 = new Set(getLetters2('abc', 2)); console.log(...set4); console.log(set4.size);
Las funciones del generador de estos ejemplos podrían simplemente escribirse para que no se repitan, pero si la función del generador es más complicada y siempre que lo siguiente no afecte el rendimiento de manera demasiado negativa, puede usar el método Set para ayudar a obtener solo valores de un generador que no no repetir.
Si desea saber más sobre los sets sin leer el capítulo de su libro del Dr. Rauschmayer, puede consultar los documentos de MDN en Set . MDN también tiene más ejemplos de iterar sobre un conjunto como el uso
forEach
y el uso de los.keys
,.values
y.entries
métodos. MDN también tiene ejemplos como unión de conjuntos, intersección de conjuntos, diferencia de conjuntos, diferencia de conjuntos simétricos y comprobación de superconjuntos de conjuntos. Con suerte, la mayoría de esas operaciones estarán disponibles en JavaScript sin necesidad de crear sus propias funciones que las respalden. De hecho, existe esta propuesta TC39 para nuevos métodos Set que, con suerte, deberían agregar los siguientes métodos a Set en JavaScript en algún momento futuro si la propuesta alcanza la etapa 4:fuente
Utilizo objetos dict como conjuntos. Esto funciona con cadenas y números, pero supongo que causaría problemas si quisiera tener un conjunto de objetos utilizando operadores personalizados de igualdad y comparación:
Creando un set:
var example_set = { 'a':true, 'b':true, 'c':true }
Prueba para su inclusión en un conjunto
if( example_set['a'] ){ alert('"a" is in set'); }
Agregar un elemento a un conjunto
example_set['d'] = true;
Eliminar un elemento de un conjunto
delete example_set['a']
;fuente
Set
. Esto ayudó.Los conjuntos no permiten entradas duplicadas y, por lo general, no garantizan un orden predefinido. Las matrices hacen ambas cosas, violando así lo que significa ser un conjunto (a menos que realice comprobaciones adicionales).
fuente
arr[id] = {"name": "Jake"};
La primera forma es JavaScript idiomático.
Siempre que desee almacenar un par clave / valor, debe utilizar un objeto JavaScript. En cuanto a las matrices, existen varios problemas:
El índice es un valor numérico.
No es una manera fácil de verificar si un valor está en una matriz sin recorrerlo.
Un conjunto no permite duplicados. Una matriz lo hace.
fuente
Si desea crear un conjunto a partir de una matriz, simplemente haga:
let arr = [1, 1, 2, 1, 3]; let mySet = new Set(arr); // Set { 1, 2, 3 }
Esta es una sintaxis de azúcar que me gustaba bastante cuando programaba en Python, muy contento de que ES6 finalmente hizo posible hacer lo mismo.
NOTA: entonces me doy cuenta de que lo que dije no respondió directamente a su pregunta. La razón por la que tiene este "truco" en ES5 es porque el tiempo de búsqueda en un objeto por claves es significativamente más rápido (O (1)) que en una matriz (O (n)). En aplicaciones de rendimiento crítico, puede sacrificar este poco de legibilidad o intuición para un mejor rendimiento.
Pero bueno, bienvenido a 2017, donde ahora puede usar el conjunto adecuado en todos los principales navegadores modernos.
fuente
Establece en
ES6
/ES2015
:ES6
/ES2015
ahora tiene conjuntos integrados. Un conjunto es una estructura de datos que permite el almacenamiento de valores únicos de cualquier tipo, ya sean valores primitivos o referencias a objetos. Un conjunto se puede declarar utilizando elES6
constructor de conjuntos integrado de la siguiente manera:const set = new Set([1, 2, 3, 4, 5]);
Al crear un conjunto utilizando el constructor de conjuntos, nuestro objeto de conjunto recién creado hereda del
Set.prototype
. Esto tiene todo tipo de métodos y propiedades auxiliares. Esto le permite hacer fácilmente las siguientes cosas:Ejemplo:
const set = new Set([1, 2, 3, 4, 5]); // checkout the size of the set console.log('size is: ' + set.size); // has method returns a boolean, true if the item is in the set console.log(set.has(1)); // add a number set.add(6); // delete a number set.delete(1); // iterate over each element using a callback set.forEach((el) => { console.log(el); }); // remove all the entries from the set set.clear();
Compatibilidad del navegador:
Todos los navegadores principales ahora son totalmente compatibles con los conjuntos, excepto IE, donde faltan algunas funciones. Para obtener una referencia exacta, consulte los documentos de mdn .
fuente
Hay dos problemas con el uso de objetos simples de JavaScript para emular conjuntos: primero, un objeto puede tener una propiedad heredada que arruinaría el operador "in" y segundo, solo puede almacenar valores escalares de esta manera, hacer un conjunto de objetos no es posible. Por lo tanto, una implementación realista de Sets debería proporcionar métodos
add
y encontains
lugar dein
asignaciones simples y de propiedades.fuente
set={};set[{x:1}]=123;alert(set[{z:99}])
Puede probar Buckets , es una biblioteca de estructura de datos de JavaScript y tiene todo lo que necesita para manipular conjuntos.
fuente
Creación y uso básico del objeto Set 🔷
let mySet = new Set() mySet.add(2) // Set {2} mySet.add(7) // Set {2, 7} mySet.add(7) // Set {2, 7} mySet.add('my text') // Set {2, 7, 'my text'} let myObj = { a: 1, b: 2 } mySet.add(myObj) // Set {2, 7, 'my text', {...}} mySet.has(2) // true mySet.has(myObj) // true mySet.size // 4
Iteración
for (let item of mySet) console.log(item) // 2, 7, 'my text', {a:1, b:2} mySet.forEach(value => console.log(value)) // 2, 7, 'my text', {a:1, b:2}
Convertir a matriz
var myArr = Array.from(mySet) // [2, 7, 'my text', {a:1, b:2}]
fuente