javascript 配列とオブジェクト（連想配列）の違いと使い方

javascriptの配列(Array, Set, Map)とオブジェクトが似ているけど扱い方が違って混乱したので使い方をまとめました。
リストっぽいなにかを使いたいけど使い分けがわからない人はどうぞ。

#配列
###基礎
・[]で囲まれているのは配列
・値をリスト状に保持する
・Array, Set, Mapがある（配列って扱いでいいのか）

###Array 
・単純に値をリストとして保持する
（key valueのような組み合わせはない）

```js
var arr= []
arr = [1,3,"aaa","aaa"]
```

#####値の出し入れ
```js
var arr= []
arr = [1,3,"aaa"]
//最後尾に追加
arr.push("bbb")  // [1,3,"aaa","bbb"]
//最初に追加
arr.push("ccc")  // ["ccc",1,3,"aaa","bbb"]
//値の取り出し
var firstElement = arr[0]  // "ccc"
var therdElement = arr[2]  // "3"

//値の数を知る
arr.length // 5
```

#####for文
```js
var arr = [1,3,"aaa"]
for (var val of arr) {
  console.log(val); // 1,3,'aaa'
}
```

#####メソッド
よく使われるメソッドの使い方をいつくか

```js
var arr = [1,3,6,1]

//各要素を取り出してなにかする
arr.forEach(element => console.log(element)); //elementは取り出した各要素

//各要素に対してなにかした結果を新しい配列にする
var newArr = arr.map(element => {
    //処理内容
    element + 1;
}); 
// newArr = [2,4,7,2]

//要素の中から条件に当てはまる要素を抽出して新しい配列にする
var newArr = arr.filter(element => {
    element > 5;
});
// newArr = [6]

//各要素に対して処理を行った結果を一つの値にまとめる
var num = arr.reduce((acc, curr) => { 
//arrに対してfor文を回していると考えると説明しやすい。
//accはfor文が回るたびに出力される結果（戻り値）、currはその時のarr内の要素の値
//やってることは1 + 3 + 6 + 1
    return acc + curr 
});
// num = 11

```

###Set 
・値の重複ができない。

```js
var set= new Set();
var set= new Set([1,3,"aaa"]);
```

#####値の出し入れ
```js
var set= new Set();
//追加
set.add(1); 
set.add(5);
set.add(5); // すでに5があるので無効
set.add(3);
// Set {1,5,3}

//値があるかを調べる
mySet.has(5); //true

//値の削除
mySet.delete(5); // 集合から 5 を削除

//値の数を知る
set.size; // 2
```
Setはインデックスを持たないので、Arrayのようにset[0]のような値の取り出しができない。
（なので、forで取り出すか、set.has(5)のように値があるか確かめる方法を使う）

#####for文
```js
var set= new Set([1,3,"aaa"]);
for (var val of set) {
  console.log(val); // 1,3,'aaa'
}
```

#####メソッド
よく使われるメソッドの使い方をいつくか

```js
var set= new Set([1,3,"aaa"]);
//各要素を取り出してなにかする
arr.forEach(element => console.log(element)); //elementは取り出した各要素
```
Array のように`.map()`や`.filter()`はない。

#####蛇足
Arrayは値の重複ができて、Setは値の重複ができないので、Arrayの中から値の重複をなくしたい場合に下記のようにする。

```js
var arr= [1,2,4,5,5,7,3,1,4,3]
var noRepert = new Set(arr)  //Set { 1, 2, 4, 5, 7, 3 }
```

###Map 
・KeyとValueを持っている
・keyには何でも（配列でもファンクションでも文字列でも）指定できる。
・keyは重複できない。
後述のObjectと似てるが、keyがなんでもいいのが一番の違いだと思ってる。

```js
var map = new Map();
var map = new Map([["key1", 1000],["key2", 2000]]);;
```
#####値の出し入れ
```js
var map= new Map();
//追加
map.set("key1", "val1");
var a = "key2"
var b = "val2"
map.set(a, b);
var func = function(){console.log("hi")}
var func = "val3"

//値の取得
map.get(a) // "val2"
map.get("key2") // "val2"
map.get(function(){console.log("hi")}) //val3

//値の削除
map.delete("key2") 

//値の数を知る
map.size; // 2
```


#####for文
```js
for (var [key, value] of map) {
  console.log(key + ' = ' + value); //
}
```
#####メソッド

```js
var map= new Map([["key1", 1000],["key2", 2000]]);
//各要素を取り出してなにかする
map.forEach((value, key) =>{
  console.log(`[${key}] = ${value}`); //[key1] = 1000 ,[key2] = 2000
}); 
```
Array のように`.map()`や`.filter()`はない。

#オブジェクト(Object)
####基礎
・{}で囲まれているのはオブジェクト
・連想配列って名前で呼ばれることがある
・keyとvalueを持っている
・keyは重複できない

```js

obj={}
obj = {
   "key1":"val1",
   "key2":"val2"
}
```


####値の出し入れ
```js
obj = {}
//値を入れる
obj.key1 = "val1"
obj["key2"] = "val2"
console.log(obj)  // { key1: 'val1', key2: 'val2-rewrite' }

//値を上書きする
obj["key1"]= "val1-rewrite"
obj.key2 = "val2-rewrite"
console.log(obj)  // { key1: 'val1-rewrite', key2: 'val2-rewrite' }

//値を取り出す
var str = obj.key2
console.log(str)  //val2-rewrite

//keyを削除する
delete obj.key2;
console.log(obj)  // { key1: 'val1-rewrite'}

```

####メソッド
```js
obj = {
   "key1":"val1",
   "key2":"val2"
}
//オブジェクトの要素数を取得
Object.keys(obj).length
//keyの一覧を取得
Object.keys(obj) //key1, key2
//valueの一覧を取得
Object.values(obj) //val1, val2
//プロパティ(key)があるかを調べる
obj.hasOwnProperty('key3') //false
```

####for 文
オブジェクトのfor文は　for(var key **in** obj)です。

```js
obj = {
   "key1":"val1",
   "key2":"val2"
}
for(var key in obj){
   console.log(key) // key1, key2
   console.log(obj[key]) // val1, val2
}
```

####蛇足
Objectは配列ではないので、`.map()`とか　`forEach()`とか使えない。
そこで、Object.keys(obj).map()のようにObjectからkeyだけを配列として取り出せば配列っぽい扱いができる。

```js
obj = {
   "key1":"val1",
   "key2":"val2"
}
Object.keys(obj).forEach(key =>{
   console.log(obj[key]) //val1 , val2
})
```

#最後に
使い分け的にはこうなる。
**単純に値をリスト保持したい**
　→　Array
**値の重複を許さず、値を保持したい**
　→　Set

**Key,Valueという形で値を持ちたい**
　Object　または Map

objectとMapはどちらもkey, valueを保持できるようなので使い分けに悩が、下記によれば
　Object→keyは　Stringとsymbol（雑にいうと変数的なもの）のみ
　Map→どんな値でも（functionや配列でも）keyになる。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map