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などのループ処理実行すればうまくいきます。

カテゴリー: JavaScript