2010-12-01 36 views
59

Hay los siguientes resultados de la consulta: (key1 y clave2 podrían ser cualquier texto)matrices asociativas multi-dimensionales en JavaScript

id key1  key2  value 

1 fred  apple 2 
2 mary  orange 10 
3 fred  banana 7 
4 fred  orange 4 
5 sarah melon 5 
... 

y deseo para almacenar los datos en una cuadrícula (tal como una matriz) looping todos los registros de la siguiente manera:

  apple orange banana melon 
fred  2  4   7  - 
mary  -  10  -  - 
sarah  -  -   -  5 

En PHP esto sería muy fácil, utilizando matrices asociativas:

$result['fred']['apple'] = 2; 

Pero en JavaScript las matrices asociativas como esta no funcionan. Después de leer toneladas de tutorial, todo lo que pude conseguir fue la siguiente:

arr=[]; 
arr[1]['apple'] = 2; 

pero arr['fred']['apple'] = 2; no funciona. Intenté matrices de objetos, pero las propiedades de los objetos no pueden ser texto libre. Cuanto más estaba leyendo tutoriales, más me confundí ...

Cualquier idea es bienvenida :)

+0

Gracias por las respuestas, pero estoy bucle a través de los resultados de la consulta, y yo desea establecer los valores uno a la vez. Las líneas de ejemplo (tomadas del ejemplo de Matt) 'var grid = {}; grid ['aa'] ['bb'] = 1;' returns "Unkeught TypeError: No se puede establecer la propiedad 'bb' de undefined". Podría estar equivocado, pero con la mayoría de sus ejemplos tengo que saber los datos en el momento de la inicialización. – Omiod

+0

Acabo de encontrar que 'var grid = {}; grid ['aa'] = {}; grid ['aa'] ['bb'] = 1; 'funciona. Una prueba más compleja falla, pero parece que estoy en el camino correcto – Omiod

+1

primero tiene que inicializar el subobjeto, como mencioné en mi respuesta. var grid = {}; grd ['aa'] = {}; * entonces * puede hacer la grilla ['aa'] ['bb'] = 1. Hay muchas maneras de verificar si el subobjeto ya está inicializado (como se menciona en mi respuesta), por lo que no sobrescribe un objeto existente. – Matt

Respuesta

121

Simplemente use un objeto JavaScript regular, que 'leería' de la misma manera que sus matrices asociativas. También debes recordar inicializarlos primero.

var obj = {}; 

obj['fred'] = {}; 
if('fred' in obj){ } // can check for the presence of 'fred' 
if(obj.fred) { } // also checks for presence of 'fred' 
if(obj['fred']) { } // also checks for presence of 'fred' 

// The following statements would all work 
obj['fred']['apples'] = 1; 
obj.fred.apples = 1; 
obj['fred'].apples = 1; 

// or build or initialize the structure outright 
var obj = { fred: { apples: 1, oranges: 2 }, alice: { lemons: 1 } }; 

Si usted está mirando por encima de los valores, que podría tener algo que se parece a esto:

var people = ['fred', 'alice']; 
var fruit = ['apples', 'lemons']; 

var grid = {}; 
for(var i = 0; i < people.length; i++){ 
    var name = people[i]; 
    if(name in grid == false){ 
     grid[name] = {}; // must initialize the sub-object, otherwise will get 'undefined' errors 
    } 

    for(var j = 0; j < fruit.length; j++){ 
     var fruitName = fruit[j]; 
     grid[name][fruitName] = 0; 
    } 
} 
+0

Administrado para usar el ejemplo en el código de producción (una extensión de Chrome), y funciona bien. Gracias. Finalmente Estoy obteniendo cómo manejar el objeto en JS! – Omiod

+3

No se puede votar esta respuesta lo suficiente! La parte que causaba que mi objeto volviera continuamente indefinido era que NO estaba inicializando el subobjeto. ** Así que asegúrese de hacer esto ! ** _ejemplo: _ 'grid [nombre] = {};' –

+0

@iSofia eres bienvenido – Matt

3

No utilice una matriz, utilice un objeto.

 var foo = new Object(); 
+1

no use un 'nuevo Objeto()', ya que el Object.prototype podría tener rarezas adjuntas ; use el objeto literal: 'var foo = {};' –

+0

@Michael Pensé que {} era solo azúcar sintáctica para el nuevo Object(); Al igual que [] es la abreviatura de la nueva matriz ( – Matt

+0

) desde mi consola Chrome JS, ambos conceptos parecen idénticos, incluidos sus prototipos. Incluso la adición de Object.prototype.foo = function() {} aparece en ambos. – Matt

9

Javascript es flexible:

var arr = { 
    "fred": {"apple": 2, "orange": 4}, 
    "mary": {} 
    //etc, etc 
}; 

alert(arr.fred.orange); 
alert(arr["fred"]["orange"]); 
for (key in arr.fred) 
    alert(key + ": " + arr.fred[key]); 
+7

Diría que el nombre de la variable 'arr' es un nombre inapropiado aquí, porque en realidad no es una matriz, sino un objeto. – Matt

21

si no tienen a ser una matriz, se puede crear un objeto JS "multidimensional" ...

<script type="text/javascript"> 
var myObj = { 
    fred: { apples: 2, oranges: 4, bananas: 7, melons: 0 }, 
    mary: { apples: 0, oranges: 10, bananas: 0, melons: 0 }, 
    sarah: { apples: 0, oranges: 0, bananas: 0, melons: 5 } 
} 

document.write(myObject[ 'fred' ][ 'apples' ]); 
</script> 
+0

JSON es en realidad el formato 'codificado' del objeto JavaScript. Lo que tienes allí no es JSON, solo un objeto de JavaScript. – Matt

+0

Gracias, Matt. Actualizó la publicación. – charliegriefer

+0

@charliegriefer, no debería la línea document.write ser: "document.write (myObj ......" – john

6

ya que necesitaba obtener todos los elementos de una buena manera me encontré con este SO tema. atravesar 2 dimensiones matriz asociativa/objeto - no importa el nombre para mí, porque la funcionalidad cuenta

var imgs_pl= {'offer':{'img':'wer-handwritter_03.png','left': 1,'top': 2 }, 
    'portfolio':{'img':'wer-handwritter_10.png','left': 1,'top': 2 }, 
    'special':{'img':'wer-handwritter_15.png','left': 1,'top': 2 } 
    }; 
    for (key in imgs_pl){ 
     console.log(key); 
     for (subkey in imgs_pl[key]){ 
      console.log(imgs_pl[key][subkey]); 
     }//for 

    }//for 
3

obtener el valor de un conjunto de propiedades de las matrices asociativas, cuando el nombre de la propiedad es un entero:

A partir de una matriz asociativa, donde los nombres de propiedad son números enteros:

var categories = [ 
    {"1":"Category 1"}, 
    {"2":"Category 2"}, 
    {"3":"Category 3"}, 
    {"4":"Category 4"} 
]; 

elementos de empuje en la matriz:

categories.push({"2300": "Category 2300"}); 
categories.push({"2301": "Category 2301"}); 

Extiende la matriz y haz algo con el valor de la propiedad.

for (var i = 0; i < categories.length; i++) { 
    for (var categoryid in categories[i]) { 
     var category = categories[i][categoryid]; 
     // log progress to the console 
     console.log(categoryid + " : " + category); 
     // ... do something 
    } 
} 

salida de la consola debe tener este aspecto:

1 : Category 1 
2 : Category 2 
3 : Category 3 
4 : Category 4 
2300 : Category 2300 
2301 : Category 2301 

Como se puede ver, se puede conseguir alrededor de la limitación matriz asociativa y tienen un nombre de propiedad sea un número entero.

NOTA: La matriz asociativa en mi ejemplo es la json que tendría si serializara un objeto Dictionary [].

2

Parece que para algunas aplicaciones, hay un enfoque mucho más simple para las matrices asociativas multidimensionales en javascript.

1) Dado que la representación interna de todas las matrices son en realidad objetos de objetos, se ha demostrado que el tiempo de acceso para los elementos indexados numéricamente es realmente el mismo que para los elementos indexados asociativos (texto).

2) el tiempo de acceso para los elementos indexados asociativos de primer nivel no aumenta a medida que aumenta el número de elementos reales.

Dado esto, puede haber muchos casos en los que es mejor utilizar un enfoque de cadena concatenada para crear la equivalencia de un elemento multidimensional. Por ejemplo:

store['fruit']['apples']['granny']['price] = 10 
store['cereal']['natural']['oats']['quack'] = 20 

va a:

store['fruit.apples.granny.price'] = 10 
store['cereal.natural.oats.quack'] = 20 

Las ventajas incluyen:

  • hay necesidad de inicializar sub-objetos o encontrar la manera de combinar mejor los objetos
  • solo nivel tiempo de acceso. los objetos dentro de los objetos necesitan N veces el tiempo de acceso
  • pueden usar Object.keys() para extraer toda la información de dimensión y ...
  • pueden usar la función regex.test (string) y la función array.map en las teclas para saca exactamente lo que quieras
  • sin jerarquía en las dimensiones.
  • el "punto" es arbitraria - con ayuda de relieve en realidad hace expresiones regulares más fácil
  • Hay un montón de guiones para "aplanar" JSON dentro y fuera de este formato, así
  • puede utilizar todas las otras funciones de procesamiento buen conjunto en keylist
0

<script language="javascript"> 
 

 
// Set values to variable 
 
var sectionName = "TestSection"; 
 
var fileMap = "fileMapData"; 
 
var fileId = "foobar"; 
 
var fileValue= "foobar.png"; 
 
var fileId2 = "barfoo"; 
 
var fileValue2= "barfoo.jpg"; 
 

 
// Create top-level image object 
 
var images = {}; 
 

 
// Create second-level object in images object with 
 
// the name of sectionName value 
 
images[sectionName] = {}; 
 

 
// Create a third level object 
 
var fileMapObj = {}; 
 

 
// Add the third level object to the second level object 
 
images[sectionName][fileMap] = fileMapObj; 
 

 
// Add forth level associate array key and value data 
 
images[sectionName][fileMap][fileId] = fileValue; 
 
images[sectionName][fileMap][fileId2] = fileValue2; 
 

 

 
// All variables 
 
alert ("Example 1 Value: " + images[sectionName][fileMap][fileId]); 
 

 
// All keys with dots 
 
alert ("Example 2 Value: " + images.TestSection.fileMapData.foobar); 
 

 
// Mixed with a different final key 
 
alert ("Example 3 Value: " + images[sectionName]['fileMapData'][fileId2]); 
 

 
// Mixed brackets and dots... 
 
alert ("Example 4 Value: " + images[sectionName]['fileMapData'].barfoo); 
 

 
// This will FAIL! variable names must be in brackets! 
 
alert ("Example 5 Value: " + images[sectionName]['fileMapData'].fileId2); 
 
// Produces: "Example 5 Value: undefined". 
 

 
// This will NOT work either. Values must be quoted in brackets. 
 
alert ("Example 6 Value: " + images[sectionName][fileMapData].barfoo); 
 
// Throws and exception and stops execution with error: fileMapData is not defined 
 

 
// We never get here because of the uncaught exception above... 
 
alert ("The End!"); 
 
</script>

0

no es necesario utilizar necesariamente objetos, puede hacerlo con múltiples dimensiones normales Al Arrays.

Esta es mi solución sin objetos:

// Javascript 
const matrix = []; 

matrix.key1 = [ 
    'value1', 
    'value2', 
]; 

matrix.key2 = [ 
    'value3', 
]; 

que a PHP es equivalente a:

// PHP 
$matrix = [ 
    "key1" => [ 
     'value1', 
     'value2', 
    ], 
    "key2" => [ 
     'value3', 
    ] 
]; 
Cuestiones relacionadas