¿Las claves de las matrices asociativas javascript deben ser cadenas, o pueden ser cualquier objeto?¿Las claves de las matrices asociativas javascript deben ser cadenas, o pueden ser cualquier objeto?
¿Las claves de las matrices asociativas javascript deben ser cadenas, o pueden ser cualquier objeto?
Respuesta
¿Estás hablando de objetos Javascript (JSON)?
La especificación dice que las claves deben ser cadenas http://json.org/.
Pero el intérprete de JavaScript permite a la vez {"key": "val"}
y {key: "val"}
No hay matrices asociativas nativas en JavaScript, sólo los objetos. Los objetos tienen propiedades. Los nombres de las propiedades son siempre cadenas: incluso los índices numéricos de las matrices will be converted to strings antes de que ocurra la 'magia de matriz'.
Si está buscando matrices asociativas con claves arbitrarias, look here.
he implementado Javascript HashMap qué código se puede obtener de http://github.com/lambder/HashMapJS/tree/master
Las claves y los valores pueden ser objetos JavaScript arbitrario. No hay requisitos sobre los objetos utilizados como claves o valores.
El mecanismo es trivial. Para cada clave, se genera una identificación única (por instancia de HashMap). Ese id. Se inyecta en el objeto clave bajo alto poco probable que colisione el nombre de campo;)
Esa id se utiliza luego para introducir el objeto de asociación JavaScript javascript subyacente.
Aquí está el código:
/*
=====================================================================
@license MIT
@author Daniel Kwiecinski <[email protected]>
@copyright 2009 Daniel Kwiecinski.
@end
=====================================================================
*/
var HashMap = function() {
this.initialize();
}
HashMap.prototype = {
hashkey_prefix: "<#HashMapHashkeyPerfix>",
hashcode_field: "<#HashMapHashkeyPerfix>",
initialize: function() {
this.backing_hash = {};
this.code = 0;
},
/*
maps value to key returning previous assocciation
*/
put: function(key, value) {
var prev;
if (key && value) {
var hashCode = key[this.hashcode_field];
if (hashCode) {
prev = this.backing_hash[hashCode];
} else {
this.code += 1;
hashCode = this.hashkey_prefix + this.code;
key[this.hashcode_field] = hashCode;
}
this.backing_hash[hashCode] = value;
}
return prev;
},
/*
returns value associated with given key
*/
get: function(key) {
var value;
if (key) {
var hashCode = key[this.hashcode_field];
if (hashCode) {
value = this.backing_hash[hashCode];
}
}
return value;
},
/*
deletes association by given key.
Returns true if the assocciation existed, false otherwise
*/
del: function(key) {
var success = false;
if (key) {
var hashCode = key[this.hashcode_field];
if (hashCode) {
var prev = this.backing_hash[hashCode];
this.backing_hash[hashCode] = undefined;
if(prev !== undefined)
success = true;
}
}
return success;
}
}
//// Usage
// creation
var my_map = new HashMap();
// insertion
var a_key = {};
var a_value = {struct: "structA"};
var b_key = {};
var b_value = {struct: "structB"};
var c_key = {};
var c_value = {struct: "structC"};
my_map.put(a_key, a_value);
my_map.put(b_key, b_value);
var prev_b = my_map.put(b_key, c_value);
// retrieval
if(my_map.get(a_key) !== a_value){
throw("fail1")
}
if(my_map.get(b_key) !== c_value){
throw("fail2")
}
if(prev_b !== b_value){
throw("fail3")
}
// deletion
var a_existed = my_map.del(a_key);
var c_existed = my_map.del(c_key);
var a2_existed = my_map.del(a_key);
if(a_existed !== true){
throw("fail4")
}
if(c_existed !== false){
throw("fail5")
}
if(a2_existed !== false){
throw("fail6")
}
Bon Appétit, Daniel Kwiecinski
Basándose en la idea de Lambder, he implementado una pequeña biblioteca de estructuras de datos.
Lo he probado un poco y todo parece funcionar.
También asigna automáticamente una identificación única a cada HashTable/HashSet que se utiliza para identificar de forma única la propiedad de la clave del objeto.
var DataStructure = {};
DataStructure.init = function(){
DataStructure.initHashables();
delete DataStructure.initHashables;
}
DataStructure.initHashables = function(){
var objectHashableIndexer = new DataStructure.Indexer();
DataStructure.Hashable = function(){
var self = this;
// Constant
//
//
const ERROR_KEY_DOES_NOT_EXIST = "Key doesn't exists in Hashable when trying to pop. Associated Key Object and Hashable logged to console.";
const HASH_MAP_KEY_PROPERTY_BASE = "DATA_STRUCTURE_HASH_MAP_KEY_PROPERTY_";
// Attributes
//
//
var tableNumber = objectHashableIndexer.getIndex();
var tableKeyProperty = HASH_MAP_KEY_PROPERTY_BASE + tableNumber.toString();
self.tableKeyProperty = tableKeyProperty;
var indexer = new DataStructure.Indexer();
var data = {};
self.data = data;
// Methods
//
//
self.getObjectKey = function(){
return indexer.getIndex().toString();
}
self.putBackObjectKey = function(index){
indexer.putBackIndex(parseInt(index));
}
var getObjectKey = self.getObjectKey;
var putBackObjectKey = self.putBackObjectKey;
self.exists = function(key){
if (!(tableKeyProperty in key))
return false;
var realKey = key[tableKeyProperty];
if (!(realKey in data))
return false;
return true;
}
self.pop = function(key){
if (!self.exists(key)){
console.log(key);
console.log(self);
throw ERROR_KEY_DOES_NOT_EXIST;
}
else{
var realKey = key[tableKeyProperty];
delete key[tableKeyProperty];
delete data[realKey];
putBackObjectKey(realKey);
}
}
self.destroy = function(){
objectHashableIndexer.putBackIndex(tableNumber);
delete self;
}
}
/*
Class DataStructure.ObjectHashMap
Purpose: Provides a way to hash arbitrary objects to values.
Prototype Arguments:
Attributes:
Methods:
Notes:
Should call inherited method destroy() when done with table to preserve indexes
*/
DataStructure.ObjectHashMap = function(){
DataStructure.Hashable.call(this);
var self = this;
// Constant
//
//
const ERROR_KEY_EXISTS = "Key already exists in ObjectHashMap when trying to push. Associated Key Object and ObjectHashMap logged to console.";
const ERROR_KEY_DOES_NOT_EXIST = "Key doesn't exists in ObjectHashMap when trying to getValue. Associated Key Object and ObjectHashMap logged to console.";
// Attributes
//
//
var tableKeyProperty;
var data;
// Initialization
//
//
self.init = function(){
self.privatize();
delete self.privatize;
}
self.privatize = function(){
tableKeyProperty = self.tableKeyProperty;
delete self.tableKeyProperty;
getObjectKey = self.getObjectKey;
delete self.getObjectKey;
putBackObjectKey = self.putBackObjectKey;
delete self.putBackObjectKey;
data = self.data;
delete self.data;
}
// Methods
//
//
var getObjectKey;
var putBackObjectKey;
self.push = function(key, value){
if (self.exists(key)){
console.log(key);
console.log(self);
throw ERROR_KEY_EXISTS;
}
else{
var realKey = getObjectKey();
key[tableKeyProperty] = realKey;
data[realKey] = value;
}
}
self.getValue = function(key){
if(!self.exists(key)){
console.log(key);
console.log(self);
throw ERROR_KEY_DOES_NOT_EXIST;
}
else{
var realKey = key[tableKeyProperty];
return data[realKey];
}
}
self.init();
delete self.init;
}
/*
Class DataStructure.ObjectHashSet
Purpose: Provides a way to store arbitrary objects and check that they exist.
Prototype Arguments:
Attributes:
Methods:
Notes:
Should call inherited method destroy() when done with table to preserve indexes
*/
DataStructure.ObjectHashSet = function(){
DataStructure.Hashable.call(this);
var self = this;
// Constant
//
//
const ERROR_KEY_EXISTS = "Key already exists in ObjectHashSet when trying to push. Associated Key Object and ObjectHashSet logged to console.";
const ERROR_KEY_DOES_NOT_EXIST = "Key doesn't exists in ObjectHashSet when trying to getValue. Associated Key Object and ObjectHashSet logged to console.";
// Attributes
//
//
var tableKeyProperty;
var data;
// Initialization
//
//
self.init = function(){
self.privatize();
delete self.privatize;
}
self.privatize = function(){
tableKeyProperty = self.tableKeyProperty;
delete self.tableKeyProperty;
getObjectKey = self.getObjectKey;
delete self.getObjectKey;
putBackObjectKey = self.putBackObjectKey;
delete self.putBackObjectKey;
data = self.data;
delete self.data;
}
// Methods
//
//
var getObjectKey;
var putBackObjectKey;
self.push = function(key){
if (self.exists(key)){
console.log(key);
console.log(self);
throw ERROR_KEY_EXISTS;
}
else{
var realKey = getObjectKey();
key[tableKeyProperty] = realKey;
data[realKey] = "";
}
}
self.init();
delete self.init;
}
}
DataStructure.Indexer = function(){
var self = this;
// Constant
//
//
const DEFAULT_SIZE = 1000;
// Attributes
//
//
var nextIndex = 0;
var availableIndicies = 0;
var freeIndicies = [];
// Initialization
//
//
self.init = function(){
freeIndicies.length = DEFAULT_SIZE;
}
// Methods
//
//
self.getIndex = function(){
var index = 0;
if (availableIndicies === 0){
index = nextIndex;
++nextIndex;
}
else{
--availableIndicies;
index = freeIndicies[availableIndicies];
}
return index;
}
self.putBackIndex = function(index){
if (availableIndicies === freeIndicies.length)
freeIndicies.push(index);
else
freeIndicies[availableIndicies] = index;
++availableIndicies;
}
self.init();
delete self.init;
}
DataStructure.init();
delete DataStructure.init;
- 1. claves deben ser cadenas o símbolos
- 2. Las claves foráneas deben ser Index en mySQL?
- 3. ¿Las llaves JSON deben ser únicas?
- 4. ¿Las implementaciones IDisposable.Dispose() deben ser idempotentes?
- 5. ¿Las preferencias compartidas pueden ser privadas?
- 6. ¿Pueden las fibras de rubí ser concurrentes?
- 7. Matrices asociativas?
- 8. ¿Pueden las anotaciones Java ser unitarias?
- 9. las plantillas pueden no ser "virtuales"
- 10. ¿Están ordenadas las matrices asociativas de PHP?
- 11. matrices asociativas multi-dimensionales en JavaScript
- 12. ¿Pueden las cadenas de entrada y salida para sprintf() ser las mismas?
- 13. Usando C/Pthreads: ¿las variables compartidas deben ser volátiles?
- 14. ¿Las clases de ayudante/utilidad deben ser abstractas?
- 15. ¿Cuán diferentes deben ser las semillas al azar?
- 16. acceder a las matrices asociativas en PHP
- 17. JSON vertido un diccionario da TypeError: las claves deben ser una cadena
- 18. normas estrictas: Sólo las variables deben ser pasados por referencia
- 19. ¿Por qué las sobrecargas del operador C# deben ser estáticas?
- 20. Sólo las variables deben ser pasados por referencia - socket_select()
- 21. ¿Por qué las variables pasadas a ejecutable deben ser definitivas?
- 22. ¿Las condiciones deberían ser positivas o negativas?
- 23. ¿Cómo se filtran las matrices asociativas usando una matriz de claves en PHP?
- 24. Las matrices asociativas son locales de forma predeterminada
- 25. ¿Pueden las especializaciones de una función de plantilla ser virtuales?
- 26. Las claves externas en postgresql pueden ser violadas por el disparador
- 27. ¿Por qué las propiedades no pueden ser de solo lectura?
- 28. ¿Los contextos de datos deben ser estáticos?
- 29. ¿Cómo se implementan las matrices asociativas en PHP?
- 30. ¿Pueden las librerías F # core ser aprobadas por SQLCLR?
Me pregunto si puedo tener una estructura que funciona como un mapa en Java, donde las claves pueden ser cualquier objeto (incluso otra matriz). No tiene que declararse en json, se puede declarar como: myarray [myObject] = value. – morgancodes
¿Cómo puede la clave ser un objeto, es un identificador ... tal vez debería ser myarray [value] = myObject; –
@sktrdie Imagine esto: {['algo', 'objeto', 'como', 'clave']: 'valor'} JSON inválido, por supuesto, pero la pregunta es si es válido en JS. – ephemient