プログラミング学習

【Vue】JavaScriptのObjectとArray操作まとめ【変換/コピー/Map】

プログラミング学習

JavaScriptの配列、オブジェクト関連のまとめ記事です。vueなどもJavaScriptなので含まれます。初心者向けサンプルですが、個人的な覚書もかねて加筆しています。

基礎はUdemyで何本か適当に買いました。

【Vue】JavaScriptのObjectとArray操作まとめ

objectのkey取得

Object.keys(obj)
Object.keys(obj)[0]
Object.keys(obj)[1]

objectからarray

一時的に純粋な配列にしたい場合、便利です。

var obj = {type1: 10, type2: 9};
const array = Object.keys(obj).map(function(key) {
  return obj[key]
})
console.log(array) // --> [10, 9]

値の方を抽出できます。arrayからobjectはreduceが便利とあわせて使うと配列にしたりオブジェクトにしたりができます。

arrayからobjectはreduceが便利

Object.assignなどが使われますが、少し複雑なことをしたい場合はreduceが便利です。

const typesArray = [9, 8, 5];

const obj = typesArray.reduce((result, array, index) => {
    result['type' + (index + 1)] = array
    return result;
}, {});

console.log(obj); // { 'type1': 9, 'type2': 8, 'type3': 5 }

reduceの引数と初歩の使い方

reduceの引数は次のとおりです。

array.reduce(function(accumulator(累積), value(要素), index(省略可), array(省略可)) {
 console.log( 'reduce', accumulator, value, index, array)
}, 5)
// accは初期値の5が入り、何度もコールされて累積されていく、実際は空オブジェクトを使うことが多い。
// valueはarrayの値が順番に入る
// indexは0から

reduce()は配列内の数値や文字列を累積して減らすイメージ。だから、初歩の初歩では合計値のサンプルがでてくる。

objectからarrayの中にobject

このパターンはわりとよくあります。

const array = Object.entries(
  this.obj
).map(([key, value]) => ({ key, value }))
[
  {
    "key": "key1",
    "value": "value1"
  },
  {
    "key": "key2",
    "value": "value2"
  }
]

objectからarrayの中にobject その2

このパターンもわりとよくあります。この方がよく使いますかね。

const array = Object.entries(
  this.obj
).map(([key, value]) => ({ [key]: value }))
[
  {
    "key1": "value1"
  },
  {
    "key2": "value2"
  }
]

objectからobject

オブジェクトにしたい場合は次のとおりです。keyがidで同じものになります。

const array = Object.keys(obj).map(function(key) {
  return { id: obj[key] }
})

配列から配列のコピー

const array = ["A", "B", "C"];
const copiedArray = array.slice();

sliceは引数があると開始地点と終了地点を切り出す関数ですが、引数がないとarrayのコピーを返します。非破壊系メソッドなので、元の配列に影響ありません。

objでは使えません。

破壊と非破壊のチートシートです。

[JavaScript] Arrayメソッド破壊・非破壊チートシート - Qiita

objectを検索して指定の文字列をすべて抽出する

const newObj = obj.filter((v) => v.value === 'apple')
console.log('newObj', JSON.stringify(newObj))

上記はオブジェクトの中でappleだけ抽出する方法です。appleが複数ある場合、findだと1つだけしか抽出できないためfilterを使います。

idを検索する場合は、v.id = 1にすればOKです。

keyはそのまま、すべてのobjectのvalueを初期値に戻す(forEachやmap)

考え方としてはfor文でまわして置換するですね。すべてのセレクトボックスをチェックボックスで初期値に戻すときに使いました。

this.arr.forEach((obj) => {
  obj.value = 'none'
})
this.arr.map((obj) => {
  return (obj.value = 'none')
})

どちらでもできますが、違いとしては

mapは新しい配列。
forEachは新しい配列ではありませんが、速度が早いです。

forEachは戻り値がないため、もうちょっと混み入ってくれるとpushして別配列を生成して使う場合が多いですね。

objectの結合

基本。objectの結合は2つの方法があります。

this.obj3 = Object.assign(this.obj1, this.obj2)

ディープコピーではありません。重複データはobj2に上書きされます。

this.obj3 = { ...this.obj1, ...this.obj2 }

arrayの結合(arrayにarrayを追加)

arrayの結合は2つの方法があります。

新しい配列を作る場合は次のとおりです。

obj3 = obj1.concat(obj2)

Array.prototype.concat()。concatは浅いコピーのようです。

Array.prototype.push.apply(obj1, obj2)

Array.prototype.push.applyの方が高速のようです。obj1にobj2が追加されますが、新しい配列を作らないとちょっと都合が悪い場合もあります。

同じkeyがあった場合のobjectの結合

this.table.forEach((obj) => {
  const existring = setList.find((set) => obj.key === set.key)
  if (existring) {
   // 重複データがあった場合、existringに上書きされる
    this.result.push(Object.assign(obj, existring))
    // このような書き方もできる
    // this.result.push({ ...obj, ...existring })
  } else {
    this.result.push(obj)
  }
})

ベースとなるtableはvueのローカルのdata。
setListはfirebaseから取得したデータ。
うっかりどちらかベースなのか把握せず逆に書かないように注意。Object.assignも入れ替えるとしっかりと上書きされない。
firebaseには必要なデータしか保存してもらず割り当てるような流れ。
forEachは戻り値がないため、resultのデータを使う形。

配列の階層を減らして別の配列に入れる

this.types = this.getData.types

オブジェクトの2番目にアクセス

Objectのキーの並びは固定ではないためArrayを使う必要があります。

[javascript]オブジェクトの〇番目の要素をとる

vueのobjectのadd,clear、配列の追加削除

一瞬うまくいかなかったことがあり、調べたらこちらにまとまっていました。2記事あるようです。

【Vue】オブジェクト追加・削除には注意が必要
【Vue】配列の追加・削除には注意が必要

【Vue】配列の追加・削除には注意が必要👮 - Qiita

vueでconsole.logのobjectを表示はJSON.stringify(obj)

vueというかjavascriptの知識ですね。

console.log((obj))

でもいいけど、(…)をクリックしないとChromeで値が見れません。クリックが手間。

下記にすると値が綺麗に表示されるため、視認性がよいです。

console.log(JSON.stringify(obj))

配列内オブジェクトを別の配列でfilterする

objects: [
  { id: 'apple', text: 'りんご' },
  { id: 'pear', text: '梨' },
  { id: 'banana', text: 'バナナ' }
]
array: [apple, pear]

サーバー側に保存したデータが配列のみ。オブジェクトをフイルタリングして初期値をセットする場合なんかに使います。

const resultObj = objects.filter((obj) => {
  return array.includes(obj.id)
})
console.log('resultObj', resultObj)
>> objects: [
  { id: 'apple', text: 'りんご' },
  { id: 'pear', text: '梨' }
]

includesないに複数指定できませんが、これならOKですね。他にsomeやeveryを使ったやり方もあるかもしれません。

ちなみに、オブジェクトとオブジェクトを比較する場合、次の記事が参考になるかもしれません。

javascript filter array multiple conditions

splice(index, 1) 配列の指定要素を削除

便利。

if (arr.length > 1) {
  const arr = ['apple', 'orange', 'banana'];
  const index = 1;
  console.log(arr[index]); // => orange
  arr.splice(index, 1);
  console.log(arr); // => ['apple', 'banana'];
}

objectのindex[]にstringを追加

const index = 3
const obj = {}
obj[index] = 'apple'
スポンサーリンク

配列関連のエラー

[Vue warn]: You may have an infinite update loop in a component render function.

Vueで破壊的メソッドを使用すると、でるエラー

[Vue warn]: You may have an infinite update loop in a component render function.

たとえば、sortの場合、次のような対応が必要。

slice().sort()
 [...numbers].sort() // スプレッド構文を使う手もある

ご参考になれば幸いです。

コメント

タイトルとURLをコピーしました