JavaScriptでforEachやfilterなどのループ処理を実行した結果、”object.forEach is not a function”や”object.filter is not a function”のエラーが発生するケースがあると思います。
原因は、forEachやfilterなどのループ処理が、配列に対して実行するものだからです。解決策は「オブジェクトを配列に変換してループ処理をかける」です。
今回は、JavaScriptでオブジェクトを配列に変換する方法を2つ紹介したいと思います。もし不明な点や質問、ご指摘がありましたら、記事下のフォームからコメントをお願いします。
サンプルコード(オブジェクト)
今回解説に使用しているオブジェクトは下記です。適当なユーザー一覧を想定しました。
各オブジェクトにはユニークなkeyを指定しています。現状下記のオブジェクトにループ処理をかけると、”object.forEach is not a function”や”object.filter is not a function”のエラーが発生します。
目的通りループ処理を実行できるようにしていきたいと思います。
const object = {
"75idsygf6bs": {
name: "name1",
age: 20,
birthplace: "Japan"
},
"hvy8g7dbdcs": {
name: "name2",
age: 30,
birthplace: "USA"
},
"495790jdkssk": {
name: "name3",
age: 40,
birthplace: "India"
},
"nvbhsdugw773": {
name: "name4",
age: 50,
birthplace: "France"
},
}
オブジェクトを配列に変換する
ここからは、オブジェクトを配列に変換する方法を解説していきます。
1. Object.keys().map() を使用して配列に変換
上記のデータオブジェクトを配列に変換するには、下記の記述で実現できます。
const result = Object.keys(object)
.map((key) => {
return object[key];
})
Object.keys()
Object.keys()とは、オブジェクトプロパティのkeyを取得するために使います。
オブジェクトは、{ key: value }の形式で表現されますが、Object.keys()を使うことでオブジェクトのkeyを取得できます。実際に処理を実行してみると、オブジェクトのkeyが取得できています。
const result = Object.keys(object)
console.log(result)
// 実行結果:["75idsygf6bs", "hvy8g7dbdcs", "495790jdkssk", "nvbhsdugw773"]
map()
map() は、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。同じループ処理でもforEachと異なるのは、新しい配列を生成する点です。
今回だとコールバック関数の引数に、Object.keys()で取得したkeyを渡し、ループ処理でkeyに該当する各オブジェクトを返し、新しい配列を作っています。
処理を実行すると結果は下記のようになります。配列の中に、それぞれのオブジェクトが格納されるようになりました。
const result = Object.keys(object)
.map((key) => {
return object[key];
})
/* 実行結果
[{
age: 20,
birthplace: "Japan",
name: "name1"
}, {
age: 30,
birthplace: "USA",
name: "name2"
}, {
age: 40,
birthplace: "India",
name: "name3"
}, {
age: 50,
birthplace: "France",
name: "name4"
}] */
新しく配列が作成されたので、ループ処理(forEachやfilter)が問題なく動作するか確認しましょう。
const result = Object.keys(object)
.map((key) => {
return object[key];
})
.forEach(r => {
console.log(r)
})
/* 実行結果
------------------------
{
age: 20,
birthplace: "Japan",
name: "name1"
}
------------------------
{
age: 30,
birthplace: "USA",
name: "name2"
}
------------------------
...
*/
正常にループ処理できました。
2. Object.entries().map()を使用して配列に変換
Object.entries()を使用しても、同じようにオブジェクトを配列に変換することができます。
Object.entries(object)
.map(([key, value]) => {
return value
})
.forEach(r => {
console.log(r)
})
/* 実行結果
------------------------
{
age: 20,
birthplace: "Japan",
name: "name1"
}
------------------------
{
age: 30,
birthplace: "USA",
name: "name2"
}
------------------------
...
*/
Object.entries()
Object.keys()が、オブジェクトのkeyを返す処理だったのに対し、Object.entries()はオブジェクトのkeyを取り出し、さらにvalueを格納した新しい配列を返します。
処理を実行してみると、下記のようになります。
const result = Object.entries(object)
console.log(result)
/* 実行結果
[
["75idsygf6bs", {
age: 20,
birthplace: "Japan",
name: "name1"
}],
["hvy8g7dbdcs", {
age: 30,
birthplace: "USA",
name: "name2"
}],
["495790jdkssk", {
age: 40,
birthplace: "India",
name: "name3"
}],
["nvbhsdugw773", {
age: 50,
birthplace: "France",
name: "name4"
}]] */
さらにmap()を使用して臨む形に整形してあげれば、Object.keys().map()の処理時と同じ配列に変換できます。
const result = Object.entries(object)
.map(([key, value]) => {
return value
})
/*
[{
age: 20,
birthplace: "Japan",
name: "name1"
}, {
age: 30,
birthplace: "USA",
name: "name2"
}, {
age: 40,
birthplace: "India",
name: "name3"
}, {
age: 50,
birthplace: "France",
name: "name4"
}]
*/
あとは、forEachやfilterなどのループ処理実行すればうまくいきます。
コメント