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

おすすめのオンラインプログラミング学習

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] }
})

配列のソート(ランキング化)

ランキングはスコアだけではないでしょうから、考え方としてはオブジェクトのソートでしょう。

配列をソートしようしたら次のエラーがでました。

sort is not a function

配列に統一感がなかったため、配列を統一してランキング化しました。

Obj {"type1":11,"type2":9,"type3":10}

scoreのobjでランキング化したい場合。

const array = Object.keys(obj).map((key) => {
  return { score: obj[key] }
})
array.sort((a, b) => {
  // return a.score - b.score // 昇順
  return b.score - a.score // 降順
})
console.log('ソート済', JSON.stringify(array))

純粋な配列でランキング化したい場合。

const array = Object.keys(obj).map((key) => {
  return obj[key]
})
array.sort((a, b) => {
  return b - a // 降順
})
console.log('ソート済', JSON.stringify(array))

JavaScriptは配列のソートする際、同値の場合はブラウザにより挙動が違うようなので、その対策も考慮する必要があります。return 0;する(読んだだけで詳しくは未検証)

objのソート(別バージョン)

このobjをそのまま使いたい場合は次のようになります。

Obj {"type1":11,"type2":9,"type3":10}
const entries = Object.entries(obj)
const sorted = entries.sort((a, b) => b[1] - a[1]) // 降順

sortedObj = Object.fromEntries(sorted)
keys = Object.keys(sortedObj)
values = Object.values(sortedObj)

参考。

javascript — プロパティ値によるJavaScriptオブジェクトのソート
次のようなJavaScriptオブジェクトがあるとします。var list = { "you": 100, "me": 75, "foo": 116, "bar": 15 }; 値に基づいてプロパティを並べ替える方法はありますか?だから私はに終わるlist = { "bar": 15...

nodeのバージョンに制限がある場合、Object.fromEntriesは使えません。他の命令で代替が必要になったケースがありました。

const entries = Object.entries(obj)
const sorted = entries.sort((a, b) => b[1] - a[1]) // 降順

const sortedObj = Object.assign(
  ...sorted.map(([key, value]) => ({ [key]: value }))
)

objectをn回文繰り返す

ソートしたオブジェクトからトップ3だけ抽出する場合などに便利です。

      Array.from({ length: 3 }, (_, i) => {
        console.log('3回数ぶん、繰り返す', _, i)
        const best3 = Object.keys(obj)[i]

        console.log('best3', best3)
      })

length: 3で3回分繰り返します。
_はすべてundefined。
iは0, 1, 2です。

{ length: 3 }だけの指定や_を省くと、すべてundefinedになります。

Rangeを使うやり方など、いろいろなやり方があります。

How to create an array containing 1...N - Stack Overflow
do <something> N times (declarative syntax) - Stack Overflow

配列から配列のコピー

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

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

objでは使えません。

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

[JavaScript] Arrayメソッド破壊・非破壊チートシート - Qiita
JSのArrayメソッドで破壊非破壊がまとまっている表が欲しいな〜〜 と思ったので作りました。 チートシート メソッド名 破壊 非破壊 用途         splice() ○      配列から配列の一部を取り...

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

Math.max.applyではなく、reduceで最大値を取得

配列操作の場合はMath.max.applyを使うと融通が聞きにくいです。単純に最大値を取得するならいいのですが、最大値の名前を取得する場合など困ります。

const max = Math.max.apply(
  null,
  obj.map(function(o) {
    return o.value
  })
)

数字の最大値ではなく、最大値のキーワードが取得できます。

const maxKey = object.reduce((a, b) =>
  a.value > b.value ? a : b
).key

詳しくはこちらの記事が参考になります。

JavaScriptで配列の最大値・最小値求めるならreduceで - Qiita
JavaScriptでMath.max.applyやMath.maxに対してスプレッド構文が使えなかった時にreduceを使って最大値を求めた時のメモです。なんでreduceいいかも!と思ったのか、なんでapplyやスプレッド構文が使...
【JavaScript】配列の最大値(最小値)を取得するには reduce を使うのがいいらしい - Qiita
要素が数値のみからなる配列の最大値(もしくは最小値)を取得する方法について調べた結果、いろいろな方法が見つかったので、記録しておきます。 要約 配列の最大値を取得するなら、reduce を使うのが better Math.m...

最大値の2番目、3番目を取り出すならソートするのが早そうです。

reduceは万能型であり、他にもいろいろなことができますよ。

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

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

[javascript]オブジェクトの〇番目の要素をとる|teratail
Javascriptでオブジェクトの〇番目の要素(?)をとる方法を知りたいです。 var obj={ "a":"apple""c":"cat""f":"fish}で上から2番目("c":"cat")を取得する方法はあるのでしょうか?

配列の空判定

空じゃない。すなわち0じゃない。

if ( array.length > 0)

省略すると、

if ( array.length )

空の場合は!をつければいいだけです。

if ( !array.length )

この方法がシンプルです。

objectの空判定

配列と考え方は一緒。

Object.keys(obj).length;

ただしオブジェクトが{}じゃないと判定できません。チェックボックスをオフにした次のようなものはダメ。

obj: {
    name: "",
    age: "",
    hobby: "",
}

その場合は事前に空プロパティのkeyを削除するを取り除く必要があります。

for (const key in this.obj) {
  if (this.obj[key] === '') {
    delete this.obj[key]
  }
}

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

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

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

【Vue】配列の追加・削除には注意が必要👮 - Qiita
【Vue】オブジェクト追加・削除には注意が必要👮 の配列版です。 オブジェクトと同じく、参照するだけなら普通のJSと同だが、要素の追加・削除で嵌るポイントがあった。 既に同様の記事はあるが自分用の備忘録という意味を含めて残すことに。 ...

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

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

console.log((obj))

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

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

console.log(JSON.stringify(obj))

文字列から数字だけを抽出

正規表現を使う方法がよさそうです。

const data = 'type11'
const result = data.replace(/[^0-9]/g, '')

console.log(result) // 11

小数点の切り捨て、切り上げ、四捨五入

Math.floor // 小数点切捨て
Math.ceil // 小数点切上げ
Math.round // 小数点四捨五入
toFixed(0) // 桁数指定で小数点四捨五入
スポンサーリンク

配列関連のエラー

[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をコピーしました