Accès / processus (imbriqué) objets, tableaux ou JSON

j'ai une structure de données imbriquée contenant des objets et des tableaux. Comment puis-je extraire les informations, c'est à dire l'accès spécifique ou plusieurs valeurs (ou clés)?

par exemple:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

Comment puis-je accéder au name du deuxième article dans items ?

661
demandé sur AndrewL 2012-08-12 17:02:12

20 réponses

préliminaires

JavaScript a un seul type de données qui peut contenir des valeurs multiples: objet . Un "tableau est une forme spéciale d'objet.

(Plain) les objets ont la forme

{key: value, key: value, ...}

matrices ont la forme

[value, value, ...]

les tableaux et les objets exposent une structure key -> value . Les clés dans un tableau doivent être numériques, tandis que n'importe quelle chaîne peut être utilisée comme clé dans les objets. Les paires de valeurs clés sont également appelées "propriétés .

Les propriétés

peuvent être consultées en utilisant dot notation

const value = obj.someProperty;

ou support de la notation , si le nom de la propriété ne serait pas valide JavaScript nom de l'identificateur [spec] , ou l' le nom est la valeur d'une variable:

// the space is not a valid character in identifier names
const value = obj["some Property"];

// property name as variable
const name = "some Property";
const value = obj[name];

pour cette raison, les éléments de tableau ne peuvent être accessibles qu'en utilisant la notation de crochet:

const value = arr[5]; // arr.5 would be a syntax error

// property name / index as variable
const x = 5;
const value = arr[x];

attendez... qu'en JSON?

JSON est une représentation textuelle de données, tout comme XML, YAML, CSV, et d'autres. Pour travailler avec de telles données, il faut d'abord les convertir en types de données JavaScript, c.-à-d. tableaux et objets (et comment travailler avec ceux-ci a été juste expliqué). Comment analyser JSON est expliqué dans la question Parse JSON en JavaScript? .

autres lectures

comment accéder aux tableaux et aux objets est une connaissance JavaScript fondamentale et il est donc conseillé de lire le MDN Guide JavaScript , en particulier les sections



accès aux structures de données imbriquées

une structure de données imbriquée est un tableau ou un objet qui se réfère à d'autres tableaux ou objets, c.-à-d. que ses valeurs sont des tableaux ou des objets. On peut accéder à ces structures en appliquant consécutivement la notation par points ou crochets.

voici un exemple:

const data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

supposons que nous voulons accéder au name du deuxième article.

Voici comment nous pouvons le faire étape par étape:

comme nous pouvons le voir data est un objet, donc nous pouvons accéder à ses propriétés en utilisant la notation par points. La propriété items est accessible comme suit:

data.items

La valeur est un tableau, pour accéder à sa deuxième element, nous devons utiliser la notation bracket:

data.items[1]

cette valeur est un objet et nous utilisons à nouveau la notation par points pour accéder à la propriété name . Nous obtenons donc finalement:

const item_name = data.items[1].name;

alternativement, nous aurions pu utiliser la notation entre crochets pour n'importe laquelle des propriétés, surtout si le nom contenait des caractères qui l'auraient rendu invalide pour l'utilisation de la notation par points:

const item_name = data['items'][1]['name'];

J'essaie d'accéder à une propriété mais je n'ai que undefined ?

la plupart du temps , lorsque vous recevez undefined , l'objet/tableau n'a tout simplement pas de propriété avec ce nom.

const foo = {bar: {baz: 42}};
console.log(foo.baz); // undefined

utiliser console.log ou console.dir et inspecter la structure de l'objet / tableau. La propriété à laquelle vous tentez d'accéder pourrait en fait être définie sur un objet / tableau imbriqué.

console.log(foo.bar.baz); // 42

et si les noms de propriétés sont dynamiques et que je ne les connais pas à l'avance?

si les noms de propriétés sont inconnus ou si nous voulons accéder à toutes les propriétés d'un objet / éléments d'un tableau, nous pouvons utiliser le for...in [MDN] boucle pour les objets et le for [MDN] boucle pour les matrices à itérer sur toutes les propriétés / éléments.

objets

pour itérer toutes les propriétés de data , nous pouvons itérer sur le objet comme ainsi:

for (const prop in data) {
    // `prop` contains the name of each property, i.e. `'code'` or `'items'`
    // consequently, `data[prop]` refers to the value of each property, i.e.
    // either `42` or the array
}

Selon l'endroit où l'objet vient (et ce que vous voulez faire), vous pourriez avoir à tester à chaque itération si la propriété est vraiment une propriété de l'objet, ou c'est une propriété héritée. Vous pouvez le faire avec Object#hasOwnProperty [MDN] .

comme alternative à for...in avec hasOwnProperty , vous pouvez utiliser Object.keys [MDN] pour obtenir un tableau des noms de propriétés :

Object.keys(data).forEach(function(prop) {
  // `prop` is the property name
  // `data[prop]` is the property value
});

matrices

pour itérer tous les éléments du data.items array , nous utilisons une for boucle:

for(let i = 0, l = data.items.length; i < l; i++) {
    // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
    // we can access the next element in the array with `data.items[i]`, example:
    // 
    // var obj = data.items[i];
    // 
    // Since each element is an object (in our example),
    // we can now access the objects properties with `obj.id` and `obj.name`. 
    // We could also use `data.items[i].id`.
}

on pourrait aussi utiliser for...in pour itérer des tableaux, mais il y a des raisons pour lesquelles cela devrait être évité: Pourquoi est-ce que" pour(élément var dans la liste) " avec des tableaux est considéré comme une mauvaise pratique en JavaScript? .

avec l'augmentation prise en charge par le navigateur de ECMAScript 5, la méthode array forEach [MDN] devient une alternative intéressante aussi bien:

data.items.forEach(function(value, index, array) {
    // The callback is executed for each element in the array.
    // `value` is the element itself (equivalent to `array[index]`)
    // `index` will be the index of the element in the array
    // `array` is a reference to the array itself (i.e. `data.items` in this case)
}); 

dans les environnements supportant ES2015( ES6), vous pouvez également utiliser le for...of [MDN] boucle, qui fonctionne non seulement pour les tableaux, mais pour tous itératif :

for (const item of data.items) {
   // `item` is the array element, **not** the index
}

dans chaque itération, for...of nous donne directement l'élément suivant de l'itérable, il n'y a pas d '"index" pour accéder ou utiliser.


et si la "profondeur" de la structure des données m'était inconnue?

en plus des clés inconnues, la" profondeur " de la structure de données (c.-à-d. combien d'objets imbriqués) il a, pourrait être inconnu. La façon d'accéder aux propriétés profondément imbriquées dépend généralement de la structure exacte des données.

mais si la structure de données contient des motifs répétitifs, p.ex. la représentation d'un arbre binaire, la solution inclut typiquement récursivement [Wikipedia] accédez à chaque niveau de la structure des données.

voici un exemple pour obtenir le premier noeud foliaire d'un arbre binaire:

function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild); // <- recursive call
    }
    else if (node.rightChild) {
        return getLeaf(node.rightChild); // <- recursive call
    }
    else { // node must be a leaf node
        return node;
    }
}

const first_leaf = getLeaf(root);

const root = {
    leftChild: {
        leftChild: {
            leftChild: null,
            rightChild: null,
            data: 42
        },
        rightChild: {
            leftChild: null,
            rightChild: null,
            data: 5
        }
    },
    rightChild: {
        leftChild: {
            leftChild: null,
            rightChild: null,
            data: 6
        },
        rightChild: {
            leftChild: null,
            rightChild: null,
            data: 7
        }
    }
};
function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild);
    } else if (node.rightChild) {
        return getLeaf(node.rightChild);
    } else { // node must be a leaf node
        return node;
    }
}

console.log(getLeaf(root).data);

une façon plus générique d'accéder à une structure de données imbriquée avec des clés et une profondeur inconnues est de tester le type de la valeur et d'agir en conséquence.

voici un exemple qui ajoute toutes les valeurs primitives à l'intérieur d'une structure de données imbriquée dans un tableau (en supposant qu'il ne contient aucune fonction). Si nous rencontrons un objet (ou un tableau), nous appelons simplement toArray encore une fois sur cette valeur (appel récursif).

function toArray(obj) {
    const result = [];
    for (const prop in obj) {
        const value = obj[prop];
        if (typeof value === 'object') {
            result.push(toArray(value)); // <- recursive call
        }
        else {
            result.push(value);
        }
    }
    return result;
}

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};


function toArray(obj) {
  const result = [];
  for (const prop in obj) {
    const value = obj[prop];
    if (typeof value === 'object') {
      result.push(toArray(value));
    } else {
      result.push(value);
    }
  }
  return result;
}

console.log(toArray(data));


Helpers

comme la structure d'un objet complexe ou d'un tableau n'est pas nécessairement évidente, nous pouvons inspecter la valeur à chaque étape pour décider comment aller plus loin. console.log [MDN] et console.dir [MDN] aidez-nous à le faire. Par exemple (sortie de la console Chrome):

> console.log(data.items)
 [ Object, Object ]

ici nous voyons que data.items est un tableau avec deux éléments qui sont deux objets. Dans la console Chrome, les objets peuvent même être agrandis et inspectés immédiatement.

> console.log(data.items[1])
  Object
     id: 2
     name: "bar"
     __proto__: Object

cela nous dit que data.items[1] est un objet, et après expansion on voit qu'il possède trois propriétés, id , name et __proto__ . Ce dernier est une propriété interne utilisée pour la chaîne prototype de l'objet. La chaîne prototype et l'héritage sont hors de portée pour cette réponse, cependant.

904
répondu Felix Kling 2017-06-16 19:10:23

vous pouvez y accéder de cette façon

data.items[1].name

ou

data["items"][1]["name"]

les deux chemins sont égaux.

50
répondu vitmalina 2013-05-14 03:29:19

dans le cas où vous essayez d'accéder à un item de la structure d'exemple par id ou name , sans savoir sa position dans le tableau, la meilleure façon de le faire serait d'utiliser underscore.js bibliothèque:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

_.find(data.items, function(item) {
  return item.id === 2;
});
// Object {id: 2, name: "bar"}

D'après mon expérience, l'utilisation de fonctions d'ordre supérieur au lieu de for ou for..in entraîne des boucles de code qui sont plus faciles à raisonner, et donc plus maintenables.

juste mes 2 cents.

22
répondu holographic-principle 2014-01-13 10:25:38

parfois, l'accès à un objet imbriqué à l'aide d'une chaîne de caractères peut être souhaitable. L'approche simple est le premier niveau, par exemple

var obj = { hello: "world" };
var key = "hello";
alert(obj[key]);//world

mais ce n'est souvent pas le cas avec les json complexes. Comme json devient plus complexe, les approches pour trouver des valeurs à l'intérieur de la json deviennent également complexes. Une approche récursive pour naviguer dans le json est la meilleure, et la façon dont cette récursion est mise à profit dépendra du type de données recherchées. Si il y a conditionnelle les déclarations en cause, un json "recherche 1519100920" peut être un bon outil à utiliser.

si la propriété consultée est déjà connue, mais que le chemin est complexe, par exemple dans cet objet

var obj = {
 arr: [
    { id: 1, name: "larry" },    
    { id: 2, name: "curly" },
    { id: 3, name: "moe" }
 ]
};

Et vous savez que vous voulez obtenir le premier résultat de la matrice dans l'objet, peut-être que vous souhaitez utiliser

var moe = obj["arr[0].name"];

Cependant, qui va provoquer une exception, car il n'y a pas de propriété de l'objet avec ce nom. Le la solution pour être en mesure d'utiliser ce serait pour aplatir l'arbre aspect de l'objet. Cela peut être fait de façon récursive.

function flatten(obj){
 var root = {};
 (function tree(obj, index){
   var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
   for(var key in obj){
    if(!obj.hasOwnProperty(key))continue;
    root[index+key+suffix] = obj[key];
    if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
    if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");   
   }
 })(obj,"");
 return root;
}

maintenant, l'objet complexe peut être aplati

var obj = previous definition;
var flat = flatten(obj);
var moe = flat["arr[0].name"];//moe

voici un jsFiddle Demo de cette approche est utilisée.

15
répondu Travis J 2017-05-23 12:10:54

objets et tableaux a beaucoup de méthodes intégrées qui peuvent vous aider avec le traitement des données.

Note: dans de nombreux exemples, j'utilise arrow functions . Elles sont similaires aux expressions de fonction , mais elles lient lexicalement la valeur this .

Object.keys() , Object.values() (ES 2017) et Object.entries() (ES 2017)

Object.keys() retourne un tableau des clés d'un objet, Object.values() retourne un tableau des valeurs de l'objet, et Object.entries() retourne un tableau des clés de l'objet et des valeurs correspondantes dans un format [key, value] .

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

console.log(Object.keys(obj)) // ['a', 'b', 'c']
console.log(Object.values(obj)) // [1, 2, 3]
console.log(Object.entries(obj)) // [['a', 1], ['b', 2], ['c', 3]]

Object.entries() avec un pour-de la boucle et de la déstructuration d'affectation

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`key: ${key}, value: ${value}`)
}

C'est très pratique pour itérer le résultat de Object.entries() avec un de la boucle et déstructuration "assignation 1519520920" .

Pour de boucle permet d'itérer les éléments du tableau. La syntaxe est for (const element of array) (nous pouvons remplacer const par var ou let , mais il est préférable d'utiliser const si nous n'avons pas l'intention de modifier element ).

tâche de déstructuration vous permet d'extraire des valeurs d'un tableau ou un objet et assignez - les à des variables. Dans ce cas, const [key, value] signifie qu'au lieu d'attribuer la [key, value] array element , nous assignons le premier élément de ce tableau à key et le deuxième élément de value . Il est équivalent à ceci:

for (const element of Object.entries(obj)) {
  const key = element[0]
       ,value = element[1]
}

comme vous pouvez le voir, la destruction rend cela beaucoup plus simple.

Array.prototype.every() et Array.prototype.some()

la "méthode 1519310920" retourne true si la fonction de rappel spécifiée retourne true pour chaque élément du tableau. La méthode some() retourne true si la fonction de rappel spécifiée retourne true pour certains (au moins un) élément.

const arr = [1, 2, 3]

// true, because every element is greater than 0
console.log(arr.every(x => x > 0))
// false, because 3^2 is greater than 5
console.log(arr.every(x => Math.pow(x, 2) < 5))
// true, because 2 is even (the remainder from dividing by 2 is 0)
console.log(arr.some(x => x % 2 === 0))
// false, because none of the elements is equal to 5
console.log(arr.some(x => x === 5))

Array.prototype.find() et Array.prototype.filter()

la méthode find() retourne le premier élément qui satisfait à la fonction de rappel fournie. La méthode filter() retourne un tableau de tous les éléments qui satisfont la fonction de rappel fournie.

const arr = [1, 2, 3]

// 2, because 2^2 !== 2
console.log(arr.find(x => x !== Math.pow(x, 2)))
// 1, because it's the first element
console.log(arr.find(x => true))
// undefined, because none of the elements equals 7
console.log(arr.find(x => x === 7))

// [2, 3], because these elements are greater than 1
console.log(arr.filter(x => x > 1))
// [1, 2, 3], because the function returns true for all elements
console.log(arr.filter(x => true))
// [], because none of the elements equals neither 6 nor 7
console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

le map() méthode retourne un tableau avec les résultats de l'appel d'une fonction de rappel fourni sur les éléments du tableau.

const arr = [1, 2, 3]

console.log(arr.map(x => x + 1)) // [2, 3, 4]
console.log(arr.map(x => String.fromCharCode(96 + x))) // ['a', 'b', 'c']
console.log(arr.map(x => x)) // [1, 2, 3] (no-op)
console.log(arr.map(x => Math.pow(x, 2))) // [1, 4, 9]
console.log(arr.map(String)) // ['1', '2', '3']

Array.prototype.reduce()

la méthode reduce() réduit un tableau à une seule valeur en appelant la fonction de rappel fournie avec deux éléments.

const arr = [1, 2, 3]

// Sum of array elements.
console.log(arr.reduce((a, b) => a + b)) // 6
// The largest number in the array.
console.log(arr.reduce((a, b) => a > b ? a : b)) // 3

la méthode reduce() prend un second paramètre facultatif, qui est la valeur initiale. C'est utile lorsque le tableau sur lequel vous appelez reduce() peut avoir zéro ou un élément. Par exemple, si nous voulions créer une fonction sum() qui prend un tableau comme argument et renvoie la somme de tous les éléments, nous pourrions l'écrire comme ceci:

const sum = arr => arr.reduce((a, b) => a + b, 0)

console.log(sum([]))     // 0
console.log(sum([4]))    // 4
console.log(sum([2, 5])) // 7
12
répondu Michał Perłakowski 2016-10-22 18:38:41

cette question est assez ancienne, donc comme une mise à jour contemporaine. Avec le début de ES2015, il y a des alternatives pour obtenir les données dont vous avez besoin. Il y a maintenant une fonctionnalité appelée déstructuration d'objet pour accéder aux objets imbriqués.

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

const {
  items: [, {
    name: secondName
  }]
} = data;

console.log(secondName);

l'exemple ci-dessus crée une variable appelée secondName à partir de la touche name à partir d'un tableau appelé items , le solitaire , dit premier objet dans le tableau.

notamment, il est probablement exagéré pour cet exemple, comme simple tableau acccess est plus facile à lire, mais il vient en utile lors de la séparation des objets en général.

c'est une introduction très brève à votre cas d'utilisation spécifique, la déstructuration peut être une syntaxe inhabituelle pour s'habituer d'abord. Je recommande la lecture de Mozilla's Destructuring Assignment documentation pour en savoir plus.

8
répondu Alex KeySmith 2016-08-25 09:32:21

utiliser JSONPath serait l'une des solutions les plus flexibles si vous êtes prêt à inclure une bibliothèque: https://github.com/s3u/JSONPath (nœud et navigateur)

pour votre cas d'utilisation le chemin json serait:

$..items[1].name

:

var secondName = jsonPath.eval(data, "$..items[1].name");
6
répondu Andrejs 2014-06-26 12:43:46

je préfère JQuery. C'est plus propre et facile à lire.

 $.each($.parseJSON(data), function (key, value) {
    alert(value.<propertyname>);
});
5
répondu Rudy Hinojosa 2016-02-24 15:55:02

pour accéder à un attribut imbriqué, vous devez spécifier son nom et ensuite chercher à travers l'objet.

si vous connaissez déjà le chemin exact, alors vous pouvez hardcode it dans votre script comme ceci:

data['items'][1]['name']

ceux - ci travaillent aussi -

data.items[1].name
data['items'][1].name
data.items[1]['name']

lorsque vous ne connaissez pas le nom exact avant main, ou un utilisateur est celui qui fournit le nom pour vous. Il faut ensuite effectuer une recherche dynamique dans la structure des données. Certains ont suggéré ici que la recherche peut être effectuée en utilisant une boucle for , mais il y a une façon très simple de parcourir un chemin en utilisant Array.reduce .

const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }
const path = [ 'items', '1', 'name']
let result = path.reduce((a,v) => a[v], data)

le chemin est une façon de dire: prenez D'abord l'objet avec la touche items , qui se trouve être un tableau. Ensuite, prenez l'élément 1 - st (tableaux d'index 0). Dernier prendre l'objet avec la touche name dans cet élément de tableau, qui se trouve être la chaîne bar .

si vous avez un très long chemin, vous pouvez même utiliser String.split pour rendre tout cela plus facile -

'items.1.name'.split('.').reduce((a,v) => a[v], data)

C'est tout simplement JavaScript, sans utiliser de bibliothèques tierces comme jQuery ou lodash.

4
répondu Evgeny 2018-02-15 10:17:33

si vous recherchez un ou plusieurs objets qui répondent à certains critères, vous avez quelques options en utilisant query-js

//will return all elements with an id larger than 1
data.items.where(function(e){return e.id > 1;});
//will return the first element with an id larger than 1
data.items.first(function(e){return e.id > 1;});
//will return the first element with an id larger than 1 
//or the second argument if non are found
data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

il y a aussi un single et un singleOrDefault ils fonctionnent un peu comme first et firstOrDefault respectivement. La seule différence est que ils vont jeter si plus qu'une correspondance est trouvée.

pour plus d'explications de query-js vous pouvez commencer par ceci post

3
répondu Rune FS 2015-06-18 08:35:05

vous pouvez utiliser lodash _get fonction:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3
3
répondu Sergey 2017-07-03 04:24:27

Le trait de Soulignement js Façon

qui est une bibliothèque JavaScript qui fournit tout un tas d'utiles functional programming helpers sans étendre des objets intégrés.

Solution:

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

var item = _.findWhere(data.items, {
  id: 2
});
if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

//using find - 

var item = _.find(data.items, function(item) {
  return item.id === 2;
});

if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}
2
répondu Mohan Dere 2016-08-13 10:50:46

Je ne pense pas que le questionneur ne concerne qu'un seul niveau d'objet imbriqué, donc je présente la démo suivante pour montrer comment accéder au noeud de l'objet JSON imbriqué. Très bien, trouvons le noeud avec l'id '5'.

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'aaa',
    items: [{
        id: 3,
        name: 'ccc'
      }, {
        id: 4,
        name: 'ddd'
      }]
    }, {
    id: 2,
    name: 'bbb',
    items: [{
        id: 5,
        name: 'eee'
      }, {
        id: 6,
        name: 'fff'
      }]
    }]
};

var jsonloop = new JSONLoop(data, 'id', 'items');

jsonloop.findNodeById(data, 5, function(err, node) {
  if (err) {
    document.write(err);
  } else {
    document.write(JSON.stringify(node, null, 2));
  }
});
<script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>
1
répondu dabeng 2017-02-22 09:00:32

question ancienne mais comme personne n'a mentionné lodash (juste souligner).

dans le cas où vous utilisez déjà lodash dans votre projet, je pense qu'une façon élégante de le faire dans un exemple complexe:

Opt 1

_.get(response, ['output', 'fund', 'data', '0', 'children', '0', 'group', 'myValue'], '')

comme:

Opt 2

response.output.fund.data[0].children[0].group.myValue

La différence entre la première et la deuxième option est que, dans le Opt 1 si vous avez une des propriétés manquantes (non définie) dans le chemin vous n'obtenez pas d'erreur, il vous renvoie le troisième paramètre.

pour le filtre de réseau lodash a _.find() mais je préfère utiliser la régulière filter() . Mais je pense toujours que la méthode ci-dessus _.get() est super utile quand on travaille avec des données vraiment complexes. J'ai affronté dans le passé APIs très complexe et il était pratique!

j'espère qu'il peut être utile pour recherche d'options pour manipuler des données vraiment complexes que le titre implique.

1
répondu Ventura 2017-07-01 11:46:35

accès dynamique à l'objet multi-niveaux.

var obj = {
  name: "salut",
  subobj: {
    subsubobj: {
      names: "I am sub sub obj"
    }
  }
};

var level = "subobj.subsubobj.names";
level = level.split(".");

var currentObjState = obj;

for (var i = 0; i < level.length; i++) {
  currentObjState = currentObjState[level[i]];
}

console.log(currentObjState);

violon de travail: https://jsfiddle.net/andreitodorut/3mws3kjL /

1
répondu Andrei Todorut 2018-03-27 20:39:14
var ourStorage = {


"desk": {
    "drawer": "stapler"
  },
  "cabinet": {
    "top drawer": { 
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};
ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

ou

//parent.subParent.subsubParent["almost there"]["final property"]

en gros, utilisez un point entre chaque descendant qui se déploie en dessous et lorsque vous avez des noms d'objets constitués de deux chaînes, vous devez utiliser la notation ["obj Name"]. Autrement, un simple point suffirait;

Source: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects

pour ajouter à ceci, accéder aux tableaux imbriqués se produirait comme ceci:

var ourPets = [
  {
    animalType: "cat",
    names: [
      "Meowzer",
      "Fluffy",
      "Kit-Cat"
    ]
  },
  {
    animalType: "dog",
    names: [
      "Spot",
      "Bowser",
      "Frankie"
    ]
  }
];
ourPets[0].names[1]; // Outputs "Fluffy"
ourPets[1].names[0]; // Outputs "Spot"

Source: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays /

1
répondu Riddick 2018-08-19 23:53:18

Un pythonic, récursive et approche fonctionnelle de démêler arbitraire JSON arbres:

handlers = {
    list:  iterate,
    dict:  delve,
    str:   emit_li,
    float: emit_li,
}

def emit_li(stuff, strong=False):
    emission = '<li><strong>%s</strong></li>' if strong else '<li>%s</li>'
    print(emission % stuff)

def iterate(a_list):
    print('<ul>')
    map(unravel, a_list)
    print('</ul>')

def delve(a_dict):
    print('<ul>')
    for key, value in a_dict.items():
        emit_li(key, strong=True)
        unravel(value)
    print('</ul>')

def unravel(structure):
    h = handlers[type(structure)]
    return h(structure)

unravel(data)

data est une liste python (tirée d'une chaîne de texte JSON):

data = [
    {'data': {'customKey1': 'customValue1',
           'customKey2': {'customSubKey1': {'customSubSubKey1': 'keyvalue'}}},
  'geometry': {'location': {'lat': 37.3860517, 'lng': -122.0838511},
               'viewport': {'northeast': {'lat': 37.4508789,
                                          'lng': -122.0446721},
                            'southwest': {'lat': 37.3567599,
                                          'lng': -122.1178619}}},
  'name': 'Mountain View',
  'scope': 'GOOGLE',
  'types': ['locality', 'political']}
]
0
répondu pX0r 2016-12-29 07:55:36

la fonction grep de jQuery vous permet de filtrer à travers un tableau:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

$.grep(data.items, function(item) {
    if (item.id === 2) {
        console.log(item.id); //console id of item
        console.log(item.name); //console name of item
        console.log(item); //console item object
        return item; //returns item object
    }

});
// Object {id: 2, name: "bar"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
0
répondu 2017-08-28 11:25:30

juste au cas où, n'importe qui visitant cette question en 2017 ou plus tard et à la recherche d'un facile à se rappeler façon, voici un poste de blog élaboré sur L'accès à des objets imbriqués dans JavaScript sans être embobiné par

ne peut pas lire la propriété " foo "non définie error

1. Oliver Steele objet imbriqué modèle de l'accès

le plus facile et le façon la plus propre est d'utiliser Oliver Steele objet imbriqué modèle de l'accès

const name = ((user || {}).personalInfo || {}).name;

avec cette note, vous ne tomberez jamais sur

ne peut pas lire le " nom "de la propriété non définie .

vous essentiellement vérifier si l'utilisateur existe, sinon, vous créez un objet vide à la volée. De cette façon, la touche de niveau suivant sera toujours accessible à partir d'un objet qui existe ou d'un objet vide , mais jamais undefined.

2. Accéder Aux Objets Imbriqués En Utilisant Le Tableau Reduce

pour pouvoir accéder aux tableaux imbriqués, vous pouvez écrire votre propre tableau réduire util.

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

Il ya aussi un excellent type manipulation bibliothèque minimale typy qui fait tout cela pour vous.

0
répondu Dinesh Pandiyan 2018-07-09 04:01:48

L'utilisation de lodash serait une bonne solution

Ex:

var object = { 'a': { 'b': { 'c': 3 } } };                                                                                               
_.get(object, 'a.b.c');                                                                                             
// => 3  
-1
répondu pradeep gowda 2017-09-27 12:34:15