482F
@482F

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

JavaScriptで配列からオブジェクトを作るベストプラクティス

JavaScriptで配列の値をキー、配列の値を加工したものを値に持つオブジェクトを作成する際のベストプラクティスを知りたいです。
例として、1から100までの整数が入った配列と引数が素数かどうかを返す関数があるとします。

const nums = Array(100).fill(0).map((_, i) => i + 1)
function isPrime(num) {
  // 素数を判定する何らかの処理...
}

上記の numsisPrime を使って、以下のようなオブジェクトを得る際の書き方についてです。

const primeMapSample = {
  1: false,
  2: true,
  3: true,
  4: false,
  // ...
  99: false,
  100: false,
}

作り方としてパッと思いついたのは以下の三つです。
この中だとどれが良い、もっと良い書き方があるといった回答を頂ければと思います。(良いと判断する基準も教えてください)
私は以下の中では三つ目の物が一番好きです。オブジェクトに値を入れていることが分かりやすく、const で完結しているためです。

// method 1
let primeMap1 = {}
for (let num of nums) {
  primeMap1[num] = isPrime(num)
}

// method 2
const primeMap2 = nums.map((num) => ({[num]: isPrime(num)}))
  .reduce((all, part) => ({...all, ...part}), {})

// method 3
const primeMap3 = nums.reduce((all, num) => 
  (all[num] = isPrime(num), all),
  {}
)
0

method 1 は let を両方とも const にしても動きます。自分が書くならこれです。ただ for-of は ECMAScript 5 以下にトランスパイルすると Iterator などの polyfill が必要になるのが難点です。レガシーブラウザをサポートするなら method 3 にします。

Object.fromEntries をサポートした環境かつ Array#map で作られる一時配列のサイズを気にしなくていい状況ならワンライナーで書いてもいいですね。

const primeMap = Object.fromEntries(nums.map((n) => [n, isPrime(n)]))

本題からは逸れますが、整数をキーとして扱うならオブジェクトではなく Map を使います。オブジェクトのキーは文字列化されてしまうので。

1Like

私が書くとすればmethod 1です。(何をしているか一目でわかりますしconstで完結します。)
for ofがダメな環境ならアロー関数もダメな気がするので、シンプルに昔からの書き方がベストかなと思います。

const nums = Array.from({ length: 100 }, (_, i) => i + 1);
function isPrime(num) {
  // 素数を判定する何らかの処理...
}

// 1
const primeMap1 = {};
for (const num of nums) {
  primeMap1[num] = isPrime(num);
}

// legacy style
var primeMapL = {};
for (var i = 1; i <= nums.length; i++) {
  primeMapL[i] = isPrime(i);
}

トリッキーですが下のような書き方もできなくはないと思います。

const nums = Array.from({ length: 101 }, (_, i) => i);
delete nums[0]; // 0はundefinedを返すようにする
const primeMap = Object.assign({}, nums.map(isPrime));

生成したオブジェクトをどのように扱うかわかりかねますが、単純に配列の0番目にundefinedでも入れておけば良いような……。

1Like

Your answer might help someone💌