TypeScript, recorriendo un diccionario


186

En mi código, tengo un par de diccionarios (como se sugiere aquí ) que está indexado en cadena. Debido a que este es un tipo un poco improvisado, me preguntaba si hay alguna sugerencia sobre cómo podría recorrer cada clave (o valor, de todas formas necesito las claves). Cualquier ayuda apreciada!

myDictionary: { [index: string]: any; } = {};

¿Intentaste for (var key in myDictionary) { }:? Dentro del bucle, usaría keypara obtener la clave y myDictionary[key]obtener el valor
Ian

@Ian Acabo de intentar eso, no parece estar funcionando. Sin errores, pero nada se ejecuta dentro de la declaración
ben657

1
@ Ian Ah, lo siento, algún código en otro lugar estaba jugando con eso. Eso funciona perfectamente! ¿Te importaría darle una respuesta para que yo pueda elegirlo?
ben657

Respuestas:


296

Para recorrer la clave / valores, use un for inciclo:

for (let key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}

8
Esto no es seguro en general; necesita la prueba hasOwnProperty (como en la respuesta de Jamie Stark) o algo más.
Don Hatch

20
@DonHatch En realidad, es muy seguro en general. No es seguro en casos muy específicos (como cuando incluye bibliotecas que modifican prototipos incorrectamente, o deliberadamente modifican prototipos incorrectamente). Depende del desarrollador si hinchar su código con comprobaciones probablemente innecesarias
Ian

1
@Ian: creo que no lo usaría sin garantías adicionales, ya que parece un accidente a la espera de que suceda, por ejemplo, si el código llega a una función de utilidad, y luego alguien pasa esa función a un diccionario que no es simplemente un Objeto, sino algo con propiedades adicionales. Sí, como usted dice, depende del desarrollador sopesar la probabilidad y la gravedad de tal escenario. Para mí, el enfoque menos oneroso mental es comportarme como si se garantizara que tal escenario sucedería en todos los casos, menos en lo que pensar.
Don Hatch

55
@Ian El problema es que hay demasiadas bibliotecas que modifican los prototipos de objetos. Parece una mala idea abogar por este tipo de patrón cuando existen alternativas mucho mejores y simples, como Object.keys(target).forEach(key => { let value = target(key); /* Use key, value here */ });. Si debe mostrar este método, al menos mencione los riesgos y las mejores alternativas para aquellos que aún no conocen mejor.
Yona Appletree

8
Ya tenemos es6 y TypeScript. ¿Por qué el problema de escribir hasOwnProperty todo el tiempo permanece sin resolver? Incluso en 2017 y con toda la atención a JS. Estoy muy decepcionado.
Gherman

170

<ES 2017 :

Object.keys(obj).forEach(key => {
  let value = obj[key];
});

> = ES 2017 :

Object.entries(obj).forEach(
  ([key, value]) => console.log(key, value);
);

Esta es la solución que estaba buscando, ya que me permitirá ordenar las claves antes de la iteración
Andrew

FYI, esto no es compatible con el campo de juegos TypeScript en este momento.
Seanny123

1
Vea aquí cómo hacer Object.entriesque funcione en TypeScript
Alex Klaus

Esto es perfecto
Piyush Choudhary

67

¿Qué tal esto?

for (let [key, value] of Object.entries(obj)) {
    ...
}

1
Requiere lib es2017 en tsconfig. Ver stackoverflow.com/questions/45422573/…
Stéphane

Esto es lo que necesitaba para superar el error de mecanografía en obj [clave] "Sin firma de índice ..." porque configuré explícitamente mi tipo de obj como {[clave: cadena]: cadena} y no quería usar {[clave: cadena]: cualquiera}. Con esto solo puedo acceder al 'valor'. Gracias
ggedde

Y si desea ignorar keyen absoluto, simplemente deje en blanco: [ , value]. (Gracias a este comentario del problema ).
Dominik

51

Hay una advertencia para el ciclo de clave / valor que Ian mencionó. Si es posible que los Objetos tengan atributos asociados a su Prototipo, y cuando use el inoperador, estos atributos se incluirán. Por lo tanto, querrá asegurarse de que la clave sea un atributo de su instancia, y no del prototipo. Los IE más antiguos son conocidos por indexof(v)aparecer como una clave.

for (const key in myDictionary) {
    if (myDictionary.hasOwnProperty(key)) {
        let value = myDictionary[key];
    }
}

3
No estoy tratando de dividir los pelos, pero como estamos hablando de script de tipo, ¿no deberías usar let key en lugar de var key? Buena respuesta gracias.
Luke Dupin

3
De hecho, con la versión actual de la secuencia de comandos tipo keyy el valuepuede ser const.
Patrick Desjardins

Es mejor no llamar al hasOwnPropertycheque desde el objeto de destino, sino hacer esto: de lo ...if (Object.prototype.hasOwnProperty.call(myDictionary, key))...contrario, si está utilizando eslint con la no-prototype-builtinsregla, emitirá un error.
sceee

6

La forma más corta de obtener todos los valores de diccionario / objeto:

Object.keys(dict).map(k => dict[k]);

1

Para obtener las llaves:

function GetDictionaryKeysAsArray(dict: {[key: string]: string;}): string[] {
  let result: string[] = [];
  Object.keys(dict).map((key) =>
    result.push(key),
  );
  return result;
}

1

Ians Answer es buena, pero debe usar const en lugar de permitir la clave porque nunca se actualiza.

for (const key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.