個々のデータ構造から離れて、それらに対する反復処理について話しましょう。
前の章では、map.keys()、map.values()、map.entries()メソッドを見ました。
これらのメソッドは汎用的であり、データ構造に使用するという共通の合意があります。独自のデータ構造を作成する場合は、それらも実装する必要があります。
これらは以下のものに対してサポートされています。
MapSetArray
プレーンオブジェクトも同様のメソッドをサポートしますが、構文はやや異なります。
Object.keys、values、entries
プレーンオブジェクトでは、次のメソッドが使用できます。
- Object.keys(obj) – キーの配列を返します。
- Object.values(obj) – 値の配列を返します。
- Object.entries(obj) –
[key, value]ペアの配列を返します。
違いに注意してください(例:mapとの比較)
| Map | オブジェクト | |
|---|---|---|
| 呼び出し構文 | map.keys() |
Object.keys(obj)ですが、obj.keys()ではありません |
| 戻り値 | イテラブル | 「実体のある」配列 |
最初の違いは、obj.keys()ではなくObject.keys(obj)を呼び出す必要があることです。
なぜそうなのか?主な理由は柔軟性です。オブジェクトはJavaScriptにおけるすべての複雑な構造の基礎であることを覚えておいてください。そのため、独自のdata.values()メソッドを実装する独自のオブジェクト(dataなど)を持つことができます。そして、それでもObject.values(data)を呼び出すことができます。
2番目の違いは、Object.*メソッドがイテラブルだけでなく、「実体のある」配列オブジェクトを返すことです。これは主に歴史的な理由によるものです。
例えば
let user = {
name: "John",
age: 30
};
Object.keys(user) = ["name", "age"]Object.values(user) = ["John", 30]Object.entries(user) = [ ["name","John"], ["age",30] ]
プロパティ値をループ処理するためにObject.valuesを使用する例を次に示します。
let user = {
name: "John",
age: 30
};
// loop over values
for (let value of Object.values(user)) {
alert(value); // John, then 30
}
for..inループと同様に、これらのメソッドはキーとしてSymbol(...)を使用するプロパティを無視します。
通常は便利です。しかし、シンボリックキーも必要であれば、シンボリックキーのみの配列を返す別のメソッドObject.getOwnPropertySymbolsがあります。また、すべてのキーを返すメソッドReflect.ownKeys(obj)も存在します。
オブジェクトの変換
オブジェクトには、配列に存在する多くのメソッド(例:map、filterなど)がありません。
それらを適用したい場合は、Object.entriesに続いてObject.fromEntriesを使用できます。
objからキー/値ペアの配列を取得するには、Object.entries(obj)を使用します。- これらのキー/値ペアを変換するには、その配列で配列メソッド(例:
map)を使用します。 - 結果の配列をオブジェクトに戻すには、
Object.fromEntries(array)を使用します。
例えば、価格を含むオブジェクトがあり、それを2倍にしたいとします。
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let doublePrices = Object.fromEntries(
// convert prices to array, map each key/value pair into another pair
// and then fromEntries gives back the object
Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
);
alert(doublePrices.meat); // 8
一見難しいように見えるかもしれませんが、一度か二度使用すれば理解しやすくなります。このようにして、強力な変換チェーンを作成できます。
コメント
<code>タグを使用し、複数行の場合は<pre>タグで囲み、10行を超える場合はサンドボックス(plnkr、jsbin、codepen…)を使用してください。