web-dev-qa-db-ja.com

(ネストした)オブジェクト、配列、またはJSONへのアクセス/処理

オブジェクトと配列を含むネストしたデータ構造があります。どのようにして情報を抽出することができますか、すなわち特定のまたは複数の値(またはキー)にアクセスすることができますか

例えば:

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

nameの2番目の項目のitemsにアクセスするにはどうすればよいですか?

713
Felix Kling

予選

JavaScriptには、複数の値を含むことができるデータ型が1つしかありません:ObjectArrayは、オブジェクトの特別な形式です。

(プレーン)オブジェクトの形式は

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

配列の形式は

[value, value, ...]

配列とオブジェクトの両方がkey -> value構造体を公開します。配列のキーは数値である必要がありますが、オブジェクトのキーとして任意の文字列を使用できます。キーと値のペアは "properties"とも呼ばれます。

プロパティには、ドット表記法を使用してアクセスできます

const value = obj.someProperty;

またはブラケット表記、プロパティ名が有効なJavaScript 識別子名ではない場合[仕様] 、または名前は変数の値です:

// 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];

そのため、配列要素にはブラケット表記を使用してのみアクセスできます。

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

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

待って... JSONはどうですか?

JSONは、XML、YAML、CSVなどと同様に、データのテキスト表現です。そのようなデータを操作するには、まずJavaScriptデータ型、つまり配列とオブジェクトに変換する必要があります(そしてそれらの操作方法については、先ほど説明しました)。 JSONの解析方法は、質問 JavaScriptでJSONを解析しますか? で説明されています。

さらに読む資料

配列とオブジェクトにアクセスする方法はJavaScriptの基本的な知識であるため、 MDN JavaScriptガイド 、特にセクションを読むことをお勧めします



ネストされたデータ構造へのアクセス

ネストされたデータ構造は、他の配列またはオブジェクトを参照する配列またはオブジェクトです。つまり、その値は配列またはオブジェクトです。このような構造には、ドット表記またはブラケット表記を連続して適用することによりアクセスできます。

以下に例を示します。

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

2番目のアイテムのnameにアクセスしたいとします。

手順を追って説明します。

ご覧のとおり、dataはオブジェクトであるため、ドット表記を使用してそのプロパティにアクセスできます。 itemsプロパティには、次のようにアクセスします。

data.items

値は配列です。2番目の要素にアクセスするには、ブラケット表記を使用する必要があります。

data.items[1]

この値はオブジェクトであり、ドット表記法を使用してnameプロパティにアクセスします。したがって、最終的には次のようになります。

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

あるいは、特にドット表記の使用では無効になる文字が名前に含まれている場合は、任意のプロパティにブラケット表記を使用できます。

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

プロパティにアクセスしようとしていますが、undefinedしか返されませんか?

ほとんどの場合、undefinedを取得しているとき、オブジェクト/配列にはその名前のプロパティがありません。

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

console.log または console.dir を使用して、オブジェクト/配列の構造を調べます。アクセスしようとしているプロパティは、ネストされたオブジェクト/配列で実際に定義されている場合があります。

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

プロパティ名が動的で、事前に知らない場合はどうなりますか?

プロパティ名が不明な場合、またはオブジェクトのすべてのプロパティ/配列の要素にアクセスする場合は、 for...inを使用できます[MDN] オブジェクトおよび forのループ[MDN] すべてのプロパティ/要素を反復処理する配列のループ。

オブジェクト

dataのすべてのプロパティを反復処理するには、次のようにobjectを反復処理できます。

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
}

オブジェクトがどこから来たのか(そして何をしたいのか)に応じて、プロパティが実際にオブジェクトのプロパティであるか、継承されたプロパティであるかを各反復でテストする必要があります。これは Object#hasOwnPropertyでできます[MDN]

hasOwnPropertyfor...inの代わりに、 Object.keysを使用できます[MDN] プロパティ名の配列を取得するには

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

配列

data.itemsarrayのすべての要素を反復処理するには、forループを使用します。

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`.
}

for...inを使用して配列を反復処理することもできますが、これを避ける必要がある理由があります: JavaScriptで配列が悪いと考えられる「for(var item in list)」はなぜですか? .

ブラウザのECMAScript 5のサポートの増加により、配列メソッド forEach[MDN] も興味深い選択肢になります。

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)
}); 

ES2015(ES6)をサポートする環境では、 for...ofも使用できます[MDN] ループ。配列だけでなく、すべての iterable でも機能します。

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

各反復で、for...ofがiterableの次の要素を直接提供します。アクセスまたは使用する「インデックス」はありません。


データ構造の「深さ」がわからない場合はどうなりますか?

不明なキーに加えて、データ構造の「深さ」(つまり、ネストされたオブジェクトの数)も不明な場合があります。深くネストされたプロパティにアクセスする方法は、通常、正確なデータ構造に依存します。

ただし、データ構造に繰り返しパターンが含まれる場合、たとえばバイナリツリーの表現、ソリューションには通常、 再帰的にが含まれます[ウィキペディア] は、データ構造の各レベルにアクセスします。

以下は、バイナリツリーの最初の葉ノードを取得する例です。

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);

未知のキーと深さを持つネストされたデータ構造にアクセスするより一般的な方法は、値の型をテストし、それに応じて行動することです。

ネストされたデータ構造内のすべてのプリミティブ値を配列に追加する例を次に示します(関数に何も含まれていない場合)。オブジェクト(または配列)に遭遇した場合は、その値に対してtoArrayを再度呼び出すだけです(再帰呼び出し)。

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));


ヘルパー

複雑なオブジェクトまたは配列の構造は必ずしも明らかではないため、各ステップで値を調べて、さらに移動する方法を決定できます。 console.log[MDN] および console.dir[MDN] これを行うのに役立ちます。例(Chromeコンソールの出力):

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

ここで、data.itemsは、両方ともオブジェクトである2つの要素を持つ配列であることがわかります。 Chromeコンソールでは、オブジェクトをすぐに展開して検査することもできます。

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

これにより、data.items[1]はオブジェクトであり、展開後、idname、および__proto__の3つのプロパティがあることがわかります。後者は、オブジェクトのプロトタイプチェーンに使用される内部プロパティです。ただし、プロトタイプチェーンと継承は、この答えの範囲外です。

1056
Felix Kling

この方法でアクセスできます

data.items[1].name

または

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

両方の方法は同じです。

58
vitmalina

itemまたはidによって、構造体例からnameにアクセスしようとしている場合は、 underscore.js libraryを使用するのが最も簡単な方法です。

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"}

私の経験上、forまたはfor..inループの代わりに高階関数を使用すると、推論が容易になり、したがって保守も容易になるコードになります。

たった2セントです。

26

時には、文字列を使用して入れ子になったオブジェクトにアクセスすることが望ましい場合があります。単純なアプローチは最初のレベルです、例えば

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

しかし、これは複雑なJSONの場合は当てはまりません。 jsonがより複雑になるにつれて、json内の値を見つけるためのアプローチも複雑になります。 JSONをナビゲートするための再帰的アプローチが最善であり、その再帰がどのように利用されるかは、検索されるデータのタイプによって異なります。条件文が含まれる場合は、 json検索 を使用するのが良いでしょう。

アクセスされているプロパティはすでにわかっているが、このオブジェクトのようにパスが複雑な場合

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

そして、あなたはあなたがオブジェクトの配列の最初の結果を得たいと思うことを知っています、おそらくあなたは使いたいです。

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

ただし、その名前のオブジェクトのプロパティがないため、例外が発生します。これを使用できるようにするための解決策は、オブジェクトのツリーの側面を平坦化することです。これは再帰的に行うことができます。

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;
}

これで、複雑なオブジェクトを平らにすることができます

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

これはjsFiddle Demoです。

16
Travis J

オブジェクトと配列には、データ処理に役立つことができる組み込みメソッドがたくさんあります。

注:多くの例で、 矢印関数を使用しています 。これらは 関数式 に似ていますが、this値を字句的にバインドします。

Object.keys()Object.values() (ES 2017)および Object.entries() (ES 2017)

Object.keys()はオブジェクトのキーの配列を返し、Object.values()はオブジェクトの値の配列を返し、Object.entries()はオブジェクトのキーの配列と対応する値を[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]]

for-ofループと構造化代入を伴うObject.entries()

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

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

Object.entries()の結果を for-ofループ および デストラクタリング代入 で繰り返すのは非常に便利です。

For-ofループを使用すると、配列要素を反復できます。構文はfor (const element of array)です(constvarまたはletに置き換えることができますが、constを変更しない場合はelementを使用することをお勧めします)。

構造化代入を使用すると、配列またはオブジェクトから値を抽出してそれらを変数に割り当てることができます。この場合、const [key, value]は、[key, value]配列をelementに代入する代わりに、その配列の最初の要素をkeyに、2番目の要素をvalueに代入することを意味します。これはこれと同等です:

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

お分かりのように、非構造化はこれをずっと簡単にします。

Array.prototype.every() および Array.prototype.some()

指定されたコールバック関数が配列の every 要素に対してtrueを返す場合、every()メソッドはtrueを返します。指定されたコールバック関数が some (少なくとも1つ)の要素に対してtrueを返す場合、some()メソッドはtrueを返します。

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() および Array.prototype.filter()

find()メソッドは、 提供されたコールバック関数を満たす最初の 要素を返します。 filter()メソッドは、提供されたコールバック関数を満たす all 要素の配列を返します。

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()

map()メソッドは、配列要素に対して提供されたコールバック関数を呼び出した結果を配列として返します。

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()

reduce()メソッドは、2つの要素を指定して提供されたコールバック関数を呼び出すことによって、配列を単一の値に縮小します。

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

reduce()メソッドはオプションの2番目のパラメータを取ります。これは初期値です。 reduce()を呼び出す配列が0個または1個の要素を持つことができるとき、これは役に立ちます。たとえば、引数として配列を取り、すべての要素の合計を返す関数sum()を作成したい場合は、次のように書くことができます。

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

14

この質問はかなり古いので、現代的な更新として。 ES2015の開始により、必要なデータを保持する代替手段があります。ネストされたオブジェクトにアクセスするためのobject destructuringという機能があります。

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

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

console.log(secondName);

上記の例は、secondNameという配列のnameキーからitemsという変数を作成します。孤独な,は、配列の最初のオブジェクトをスキップすると言います。

特に、単純な配列アクセスは読みやすいため、この例ではおそらくやり過ぎですが、一般的にオブジェクトを分解するときに役立ちます。

これは特定のユースケースの非常に簡単な紹介であり、構造化は最初は慣れるには珍しい構文です。詳細については、 MozillaのDestructuring Assignmentドキュメント を読むことをお勧めします。

11
Alex KeySmith

ライブラリを含める場合は、 JSONPath を使用するのが最も柔軟なソリューションの1つです。 https://github.com/s3u/JSONPath (node andブラウザ)

あなたのユースケースでは、JSONパスは次のようになります。

$..items[1].name

そう:

var secondName = jsonPath.eval(data, "$..items[1].name");
7
Andrejs

私はJQueryが好きです。きれいで読みやすいです。

 $.each($.parseJSON(data), function (key, value) {
    alert(value.<propertyname>);
});

6
Rudy Hinojosa

ネストした属性にアクセスするには、その名前を指定してからオブジェクトを検索する必要があります。

正確なパスがすでにわかっている場合は、次のようにそれをスクリプトにハードコーディングすることができます。

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

これらも動作します -

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

あなたが前に正確な名前を知らないとき、またはユーザがあなたのために名前を提供するものです。その場合、データ構造を動的に検索する必要があります。ここではforループを使って検索を実行できると提案した人もいますが、 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)

パスは、言い方です:最初にキーitemsを持つオブジェクトを取ります。それは偶然配列です。それから1st要素(0インデックス配列)を取ります。最後に、その配列要素のキーnameを持つオブジェクトを取り出します。これはたまたま文字列barです。

あなたが非常に長いパスを持っているならば、あなたはこれらの全てをより簡単にするためにさえString.splitを使うかもしれません -

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

これは単なる普通のJavaScriptで、jQueryやlodashのようなサードパーティのライブラリを使用していません。

6
Evgeny

lodash _get関数を使うことができます:

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

_.get(object, 'a[0].b.c');
// => 3
5
Sergey

特定の基準を満たす1つ以上のオブジェクトを探している場合は、 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:""});

singlesingleOrDefaultもあり、それぞれfirstfirstOrDefaultに似ています。唯一の違いは、 more が複数の一致が見つかった場合にスローされることです。

query-jsの詳しい説明は、この post から始めてください。

4
Rune FS

動的なマルチレベルオブジェクトへのアクセス.

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);

作業フィドル: https://jsfiddle.net/andreitodorut/3mws3kjL/

3
Andrei Todorut
var ourStorage = {


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

または

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

基本的には、その下に展開する各子孫の間にドットを使用し、2つの文字列からオブジェクト名を作成するときは、["obj Name"]表記を使用する必要があります。そうでなければ、ドットだけで十分です。

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

これに追加すると、入れ子になった配列へのアクセスは次のようになります。

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"

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

3
Johnny

アンダースコアとウェイ

これは、組み込みオブジェクトを拡張することなく、便利なfunctional programmingヘルパーの全体的な混乱を提供するJavaScriptライブラリです。

溶液:

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);
}
3
Mohan Dere

昔の質問ですが、誰もlodashについて言及していませんでした(アンダースコアのみ)。

あなたがあなたのプロジェクトですでにlodashを使っているのであれば、私はこれを複雑な例で行うためのエレガントな方法だと思います。

オプション1

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

と同じ:

オプション2

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

最初のオプションと2番目のオプションの違いは、 Opt 1 でパスのいずれかのプロパティが欠落している(未定義)場合、エラーにならないことです。3番目のパラメータが返されます。

配列フィルタの場合、lodashには_.find()がありますが、通常のfilter()を使用します。しかし、私はやはり上記のメソッド_.get()が本当に複雑なデータを扱うときにとても便利だと思います。私は過去に本当に複雑なAPIに直面しました、そしてそれは便利でした!

タイトルが意味する本当に複雑なデータを操作するためのオプションを探している人に役立つことを願っています。

3
Ventura

念のため、2017年以降にこの質問にアクセスし、簡単に覚えられるの方法を探している人がいる場合、 JavaScriptでネストされたオブジェクトにアクセスする に関する詳細なブログ記事を次に示します。によって竹

undefinedエラーのプロパティ 'foo'を読み取れません

1. Oliver Steeleのネストされたオブジェクトアクセスパターン

最も簡単でクリーンな方法は、Oliver Steeleのネストされたオブジェクトアクセスパターンを使用することです

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

この表記法を使用すると、実行することはありません

undefinedのプロパティ 'name'を読み取れません。

基本的にユーザーが存在するかどうかを確認し、存在しない場合は空のオブジェクトをその場で作成します。この方法では、次のレベルのキーは常に存在するオブジェクトまたは空のオブジェクトからアクセスされますですが、未定義からは決してアクセスされません。

2. Array Reduceを使用してネストされたオブジェクトにアクセスする

ネストされた配列にアクセスできるようにするには、独自の配列reduce 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.

最小限のライブラリを処理する優れた型もあります typy これはすべてあなたのためにこれを行います。

3
Dinesh Pandiyan

質問者が1つのレベルのネストしたオブジェクトだけに関係するとは思わないので、深くネストしたjsonオブジェクトのノードにアクセスする方法を示すために、以下のデモを提示します。それでは、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>

2
dabeng

これは動的なアプローチです-「深い」キーは文字列'items[1].name'です(配列表記[i]は任意のレベルで使用できます)-キーが無効な場合、undefinedが返されます。

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}
var data = {
    code: 42,
    items: [
      { id: 1, name: 'foo'}, 
      { id: 2, name: 'bar'},
   ]
};

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}

console.log( deep(data,'items[1].name') );
0

私のstringjsonはPHPファイルから来ていますが、それでもvarでここに示しています。私が直接jsonをobjに持っていっても、私のjsonファイルを

var obj=JSON.parse(stringjson);だから私はmessageobjを取得し、警告ボックスに表示し、私はdataを取得し、それは一つの変数ArrObjに格納され、それから私はこのArrObj[0].idのようなキー値でその配列の最初のオブジェクトを読む

     var stringjson={
        "success": true,
        "message": "working",
        "data": [{
                  "id": 1,
                  "name": "foo"
         }]
      };

                var obj=JSON.parse(stringjson);
                var key = "message";
                alert(obj[key]);
                var keyobj = "data";
                var ArrObj =obj[keyobj];

                alert(ArrObj[0].id);
0
Manthan Patel

jQueryのgrep 関数を使用すると、配列をフィルタリングできます。

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
user7110739

任意のJSONツリーを解明するためのPythonicの再帰的かつ機能的なアプローチ:

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 はPythonリストです(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
pX0r