Je suis un débutant en JavaScript et AngularJS. J'essayais de boucler un objet, d'obtenir sa paire clé-valeur, puis de l'utiliser pour créer un tableau de nouveaux objets.

var actorMovie = {
    "Leonardo DiCaprio" : "The Revenant",
    "Christian Bale" : "The Dark Knight Rises",
    "Sylvester Stallone" : "Rocky"
};

if(actorMovie){
    var actorMovieArray = [];
    angular.forEach(actorMovie, function(value, key) {
        actorMovieArray.push ({key: {
            "Movies": {
                "Best Movie": value
            }
        }});
    });
}

console.log(actorMovieArray);

Ce journal de console imprime les bonnes valeurs, mais la clé reste comme «clé» et n'est jamais mise à jour au nom de l'acteur comme prévu. Qu'est-ce que je fais mal ici? J'ai essayé de chercher une réponse mais je n'ai trouvé aucune solution. Suis-je en train de manquer quelque chose?

1
Sunil 6 mars 2016 à 13:25

3 réponses

Meilleure réponse

Je ferais quelque chose comme

angular.forEach(actorMovie, function(value, key) {
    actorMovieArray[key]= {
        "Movies": {
            "Best Movie": value
        }
    };
});

Dans votre code, javascript ne sait pas que vous souhaitez évaluer la variable key pour affecter la propriété et considère que la clé est la chaîne key.

1
Hugues Stefanski 6 mars 2016 à 10:29

Comme l'a souligné @Hugues, il n'y a aucun moyen pour JavaScript de savoir si vous entendez la clé comme littérale ou comme variable, donc la valeur littérale est utilisée.

Veuillez noter que la réponse ne se comporte pas de la même manière que vous le vouliez dans votre question. L'utilisation de la clé comme identifiant de tableau présente deux inconvénients:

  • l'ordre des articles lors de l'itération sur les clés ne peut pas être conservé
  • s'il y a deux éléments ayant la même clé (ici le nom de l'acteur), vous n'en obtiendrez qu'un dans le résultat car vous écrasez une valeur ajoutée précédemment. (ce n'est pas vraiment le cas car votre entrée est déjà un littéral d'objet de sorte que les clés en double ne sont pas un problème, mais cela pourrait être un problème lors du passage à une autre entrée, par exemple un tableau d'éléments)

Cela pourrait vous convenir tant que la commande n'a pas d'importance et que vous savez que vos clés sont uniques. Si vous souhaitez la structure telle que définie dans votre question, veuillez considérer l'extrait de code suivant:

function buildItem(value, key) {
  var res = {};
  res[key] = {
            "Movies": {
                "Best Movie": value
            }
        };
  return res;
}

if(actorMovie){
    var actorMovieArray = [];
    angular.forEach(actorMovie, function(value, key) {
        actorMovieArray.push(buildItem(value, key));
    });
}

Essayez ce jsbin: http://jsbin.com/luborejini/edit?js,console

0
Andreas Jägle 6 mars 2016 à 10:45

J'utiliserais Object.keys et Array.forEach sur le tableau résultant. Et j'embrasserais également la nature fonctionnelle de Javascript. De cette façon, vous pouvez facilement extraire la fonction de créateur dans les bibliothèques de mappage d'usine pour vos données api json.

if(actorMovie){
var actorMovieArray = [];
Object.keys(actorMovie).forEach(function(actor){
    actorMovieArray[actor] = function(){
        return {
            Movies: {
                BestMovie: actorMovie[actor]
            }
        };
    }();
});

}

Je recommanderais également de ne pas utiliser le nom de l'acteur comme clé dans le tableau. Je préfère le mapper à une structure de modèle, cela rendra vos vues / contrôleurs plus propres et plus faciles à comprendre:

if(actorMovie){
var actorMovieArray = [];
Object.keys(actorMovie).forEach(function(actor) {
    actorMovieArray.push(function(){
        return {
            Actor: actor,
            Movies: {
                BestMovie: actorMovie[actor]
            }
        };
    }());
});

}

Cela vous amènera à des modèles de vue plus concis et vous mettra en place pour une refactorisation facile une fois que votre structure est en place. Cela facilitera également les tests, du moins à mon avis.

0
Espen 6 mars 2016 à 11:01