Programming Self-Study Notebook

勉強したことを忘れないように! 思い出せるように!!

JavaScriptの文法(配列)

f:id:overworker:20200406080809j:plain:h250

配列の基本

  • 0から始まる数字(添え字、インデックス)によってアクセスする。
    • 順序を持っている(オブジェクトのプロパティとは違う)
  • JavaScriptの配列には異なる型の要素を入れることができる
    • オブジェクトや他の配列を格納することが可能
  • 配列リテラル[]を使って表現される。
    • 配列要素にも[]を使ってアクセスする。
  • lengthというプロパティーで配列の要素を知ることができる
  • 配列の最後の要素の添え字よりも大きな数字を使って代入を行うと、配列が自動的に大きくなり、値が指定されていない要素にはundefinedが暗黙のうちに代入される。
  • Arrayコンストラクタを使うこともできる(しかしあまり使われない。)

配列要素の操作

  • 配列の要素を変更してしまうメソッド(破壊的なメソッド)と新しい配列を返すメソッドがある。

先頭・最後の要素に対する操作

配列arrの先頭の要素 配列arrの最後の要素
arr[0] arr[arr.length-1]
メソッド 機能 返却値 備考
push 配列の最後に要素を追加する 変更後の配列の長さ 配列そのものを変更する
pop 配列の最後の要素を削除する 削除された要素 配列そのものを変更する
unshift 配列の先頭に要素を追加する 変更後の配列の長さ 配列そのものを変更する
shift 配列の先頭の要素を削除する 削除された要素 配列そのものを変更する

複数要素の追加

メソッド 機能 引数 返却値 備考
concat 複数の要素を配列に追加する 追加する要素 配列のコピー 破壊なし
  • 引数の個数は任意
  • 引数に配列をセットすると、配列を分解して元の配列の最後に追加する
    • ただし、引数の配列の要素が配列の場合、内側の配列は分解しない
let before = [1,2,3];
console.log(before);              // [1,2,3]
let after = before.concat(4,5,6);
console.log(after);               // [1,2,3,4,5,6]
after = before.concat([4,5,6]);
console.log(after);               // [1,2,3,4,5,6]
after = before.concat([4,5],6);
console.log(after);               // [1,2,3,4,5,6]
after = before.concat([4,5],[6,7]);
console.log(after);               // [1,2,3,4,5,6,7]
after = before.concat([4,5,[6,7]]);
console.log(after);               // [1,2,3,4,5,Array(2)] ->[1,2,3,4,5,[6,7]]

部分配列

メソッド 機能 引数 返却値 備考
slice 既存の配列の
一部を切りだす
①:切り出す開始位置
②:終了位置
配列のコピー 破壊なし
  • 第二引数で指定された要素の直前までを切り出す
    • 第二引数を指定しない場合は、最後の文字まで切り出す
  • 引数に負の値をセットすると、最後の要素から数える
let before = [1,2,3,4,5];
console.log(before);              // [1,2,3,4,5]
let after = before.slice(3);
console.log(after);               // [4,5]
after = before.slice(2,4);
console.log(after);               // [3,4]
after = before.slice(-2);
console.log(after);               // [4,5]
after = before.slice(1,-2);
console.log(after);               // [2,3]
after = before.slice(-2,-1);
console.log(after);               // [4]

途中の要素の削除や途中の要素への追加

メソッド 機能 引数 返却値 備考
splice 指定した位置の
要素(複数可)を削除し、
新たな要素を追加する
①:変更開始位置
②:削除する要素の数(0指定可)
③~:追加する要素
取り除かれた要素の配列 配列そのものを変更する
// 配列(splice)
let arr = [1,5,7];
console.log(arr);               // [1,5,7]
let res = arr.splice(1,0,2,3,4);
console.log(arr);               // [1,2,3,4,5,7]
console.log(res);               // []
res = arr.splice(5,0,6);
console.log(arr);               // [1,2,3,4,5,6,7]
console.log(res);               // []
res = arr.splice(1,2);
console.log(arr);               // [1,4,5,6,7]
console.log(res);               // [2,3]
res = arr.splice(2,1,"a","b",);
console.log(arr);               // [1,4,"a","b",6,7]
console.log(res);               // [5]

配列内の要素の削除や置換

メソッド 機能 引数 返却値 備考
copyWithin 指定した位置に
指定した位置の要素をコピーする
(上書きする)
①:コピー先開始位置
②:コピー元
(③:コピーを終了する場所)
新たに生成された配列 配列そのものを変更する
  • 第二引数、第三引数には負の値を指定することがあできる。
  • 配列の要素数は変化しない
    • コピー元データのサイズが大きく、上書き対象が存在しない場合は、はみ出た部分のみが無視される。
let origin = [1,2,3,4];
let after = origin.copyWithin(1,2);
console.log(origin);               // [1,3,4,4]
console.log(after);                // [1,3,4,4]
after = origin.copyWithin(2,0,2);
console.log(origin);               // [1,3,1,3]
console.log(after);                // [1,3,1,3]
after = origin.copyWithin(0,-3,-1);
console.log(origin);               // [3,1,1,3]
console.log(after);                // [3,1,1,3]

let origin2 = [1,2,3,4,5,6,7,8,9];
let after2 = origin2.copyWithin(6,0,6);
console.log(origin2);               // [1,2,3,4,5,6,1,2,3]
console.log(after2);                // [1,2,3,4,5,6,1,2,3]

let origin3 = [1,2,3,4,5,6,7,8,9];
let after3 = origin3.copyWithin(4,5,8);
console.log(origin3);               // [1,2,3,4,6,7,8,8,9]
console.log(after3);                // [1,2,3,4,6,7,8,8,9]

配列を特定の値で埋める

メソッド 機能 引数 返却値 備考
fill 複数の要素の値を一度に指定する ①:要素にセットしたい値
(②:開始位置)
(③:終了する場所)
新たに生成された配列 配列そのものを変更する
  • 第二引数、第三引数には負の値を指定することがあできる。
  • 配列の要素数は変化しない
    • コピー元データのサイズが大きく、上書き対象が存在しない場合は、はみ出た部分のみが無視される。
let origin = new Array(5).fill(1);
console.log(origin);               // [1,1,1,1,1]
let after = origin.fill("a");
console.log(origin);               // ["a","a","a","a","a"]
console.log(after);                // ["a","a","a","a","a"]
after = origin.fill("b",1);
console.log(origin);               // ["a","b","b","b","b"]
console.log(after);                // ["a","b","b","b","b"]
after = origin.fill("c",2,4);
console.log(origin);               // ["a","b","c","c","b"]
console.log(after);                // ["a","b","c","c","b"]
after = origin.fill(5.5,-4);
console.log(origin);               // ["a",5.5,5.5,5.5,5.5]
console.log(after);                // ["a",5.5,5.5,5.5,5.5]
after = origin.fill("e",-3,-1);
console.log(origin);               // ["a",5.5,"e","e",5.5]
console.log(after);                // ["a",5.5,"e","e",5.5]

逆転とソート

メソッド 機能 引数 返却値 備考
reverse 配列の要素を逆転させる 新たに生成された配列 配列そのものを変更する
let origin = [1,2,3,4,5];
console.log(origin);               // [1,2,3,4,5]
let after = origin.reverse();
console.log(origin);               // [5,4,3,2,1]
console.log(after);                // [5,4,3,2,1]
after = origin.reverse();
console.log(origin);               // [1,2,3,4,5]
console.log(after);                // [1,2,3,4,5]
メソッド 機能 引数 返却値 備考
sort 配列の要素を並べ替える 新たに生成された配列 配列そのものを変更する
  • sortの結果は昇順となる?
    • 降順が取得したい場合はsortの結果に対してreverseを実施する
let origin = [5,3,2,4,1];
console.log(origin);               // [5,3,2,4,1]
let after = origin.sort();
console.log(origin);               // [1,2,3,4,5]
console.log(after);                // [1,2,3,4,5]
origin.reverse();
console.log(origin);               // [5,4,3,2,1]
console.log(after);                // [5,4,3,2,1]
  • 一般的にオブジェクトもプロパティを指定して並び替えることが可能らしいが、Chromeで以下のコードを実施してみたところ変化がなかった
let origin = [{name:"Satoshi"},{name:"Takeshi"},{name:"Akira"},{name:"Koji"}];
console.log(origin); // [{name:"Satoshi"},{name:"Takeshi"},{name:"Akira"},{name:"Koji"}]
origin.sort((a,b) => a.name > b.name);
console.log(origin); // [{name:"Satoshi"},{name:"Takeshi"},{name:"Akira"},{name:"Koji"}]
origin.sort((a,b) => a.name[1] > b.name[1]);
console.log(origin); // [{name:"Satoshi"},{name:"Takeshi"},{name:"Akira"},{name:"Koji"}]

検索

indexOf(指定した値と最初に一致する要素の添え字番号を返す)、
lastIndexOf(指定した値と最後に一致する要素の添え字番号を返す)

メソッド indexOf、(lastIndexOf)
内容 指定した値と最初(最後)に一致した要素の添え字の番号を返却
比較方法 厳密比較
該当あり時の動作 添え字の番号を返却
該当なし時の動作 -1を返却
オプション 検索開始位置を指定することができる
const o = {name:"Takeshi"};
const arr = [true,5,8,"2","4","f","G",[1,2],o,null,,true,false,5,8,"2"];

console.log(arr.indexOf(5))                 // 1
console.log(arr.indexOf("f"))               // 5
console.log(arr.indexOf(4))                 // -1
console.log(arr.indexOf("4"))               // 4
console.log(arr.indexOf({name:"Takeshi"}))  // -1
console.log(arr.indexOf(o))                 // 8
console.log(arr.indexOf([1,2]))             // -1
console.log(arr.indexOf(null))              // 9
console.log(arr.indexOf(false))             // 12
console.log(arr.indexOf(undefined))         // -1
console.log(arr.indexOf(true))              // 0

console.log(arr.lastIndexOf(5))             // 13
console.log(arr.lastIndexOf("f"))           // 5

findIndex(指定した条件と最初に一致した要素の添え字の番号を返却)

メソッド findIndex
内容 指定した条件と最初に一致した要素の添え字の番号を返却
比較方法 関数内で指定
該当あり時の動作 添え字の番号を返却
該当なし時の動作 -1を返却
const arr = [{id:5,name:"Takeshi"},{id:7,name:"Hanako"}];

console.log(arr.findIndex(o => o.id === 7));                  // 1
console.log(arr.findIndex(o => o.name === "Hanako"));         // 1
console.log(arr.findIndex(o => o === 7));                     // -1
console.log(arr.findIndex(o => o === "Hanako"));              // -1
console.log(arr.findIndex(o => o === {id:7,name:"Hanako"}));  // -1
console.log(arr.findIndex(o => o == {id:7,name:"Hanako"}));   // -1
console.log(arr.findIndex(o => o === arr[1]));                // -1
console.log(arr.findIndex(o => o.id === 7));                  // 1
console.log(arr.findIndex(o => o.id === "7"));                // -1
console.log(arr.findIndex(o => o.id == "7"));                 // 1

find(指定した条件と最初に一致した要素を返却)

メソッド find
内容 指定した条件と最初に一致した要素を返却
比較方法 関数内で指定
該当あり時の動作 要素自体が返却される
該当なし時の動作 undefinedを返却
オプション 第二引数:添え字
第三引数:配列全体
const arr = [{id:5,name:"Takeshi"},{id:7,name:"Hanako"}];

console.log(arr.find(o => o.id === 7)); // {id:7,name:"Hanako"}
console.log(arr.find(o => o.id === 6)); // undefined

添え字を条件(処理の実態)で使用する例

const arr = [1,18,16,5,25,16,10,3,49,9];

console.log(arr.find((x,i) => i>2 && Number.isInteger(Math.sqrt(x)))); // 25

関数呼び出し時にthisの内容を指定する例

class Person{
  constructor(name){
    this.name = name;
    this.id =Person.nextId++;
  }
}
Person.nextId = 0;
const a = new Person("一郎"),
b = new Person("次郎"),
c = new Person("三郎"),
d = new Person("四郎");
const arr = [a,b,c,d];

// IDを使って直接比較
console.log(arr.find((p) => p.id === c.id));                       // Person {name: "三郎", id: 2}

// thisを定数"c"に指定
console.log(arr.find(function (p) { return p.id === this.id}, c)); // Person {name: "三郎", id: 2}

some(指定した条件と一致する要素の有無の判定を実施する)

メソッド some
内容 指定した条件と一致する要素が一つ以上存在することの判定を実施する
比較方法 関数内で指定
該当あり時の動作 trueが返却される
該当なし時の動作 falseを返却
const arr = [5,7,10,11,19];
console.log(arr.some(x => x%2 === 0));                      // true
console.log(arr.some(x => Number.isInteger(Math.sqrt(x)))); // false

every(すべての要素が指定した条件を満たすかの判定を実施する)

メソッド every
内容 すべての要素が指定した条件を満たすかの判定を実施する
比較方法 関数内で指定
該当あり時の動作 trueが返却される
該当なし時の動作 falseを返却
const arr = [4,6,16,36];
console.log(arr.every(x => x%2 === 0));                      // true
console.log(arr.every(x => Number.isInteger(Math.sqrt(x)))); // false

mapとfilter

map(配列内の要素を変換する)

メソッド map
内容 配列内の要素を変換する
変換方法 関数内で指定
レスポンス 新しい配列(コピー)が返却される
const lineup = [{type:"iPhone",price:54800},{type:"Android",price:49800}];
const types = lineup.map(x => x.type);
console.log(types);  // ["iPhone","Android"];
const prices = lineup.map(x => x.price);
console.log(prices);  // [54800,49800];

// priceを2割引きした、新しい配列を作成する
const lineup2 = lineup.map(x => ({
  type:x.type,
  price:x.price*0.8,
}));
console.log(lineup2); // [{type:"iPhone",price:43840},{type:"Android",price:39840}]

添え字を処理の実態で使用する例

const types = ["iPhone","Android"];
const prices = [54800,49800];
const lineup =types.map((x,i) => ({
  type: x,
  price: prices[i],
}));
console.log(lineup);

filter(配列から要素を取り去る)

メソッド filter
内容 配列内の要素を削除する
変換方法 関数内で指定
レスポンス 新しい配列(コピー)が返却される
const cards = [];
const suits = ["ハート","ダイヤ","クラブ","スペード"];
for(let suit of suits){
  for(let i= 1;i<=13;i++){
    cards.push({
      suit:suit,
      number:i,
    })
  }
}
console.log(cards);
const selected = cards.filter(card => card.number === 2);
console.log(selected);

/* selected
0: {suit: "ハート", number: 2}
1: {suit: "ダイヤ", number: 2}
2: {suit: "クラブ", number: 2}
3: {suit: "スペード", number: 2}
*/

// ここから組み合わせ
const selected2 = cards.filter(card => card.number === 1).map(x => ({suit:x.suit,number:"A"}));
console.log(selected2);

/* selected
0: {suit: "ハート", number: "A"}
1: {suit: "ダイヤ", number: "A"}
2: {suit: "クラブ", number: "A"}
3: {suit: "スペード", number: "A"}
*/

reduce(全要素に対する処理を実施した最終結果を返す)

メソッド reduce
内容 全要素に対する処理を実施した最終結果(任意の値)を返す
変換方法 関数内で指定
レスポンス 任意の値が返却される
補足 返却値の型は、関数内で何をセットするかで決まる
補足 アキュムレータの初期値は第二引数で指定可能
const arr = [1,2,3,4,5,6,7,8,9,10];

// 合計値を求める
const sum = arr.reduce((a,x) => a += x,0);
console.log(sum);  // 55

// 平均値を求める
const ave= arr.reduce((a,x) => a += x,0)/arr.length;
console.log(ave);  // 5.5

// 新しい配列を生成する
const arr2= arr.reduce((a,x) => a.concat(x+10),[]); // ※
console.log(arr2); // [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

※ concatは新しい配列を返します。Pushは新しい配列の要素数を返します。

配列関連のメソッドと削除された要素、定義されていない要素

map,filter,reduceの注意点

  • 未定義の要素に対しては関数が呼び出されない
  • 削除済みの要素に対しては関数が呼び出されない
const arr = Array(5).map(function(x){return 5});
console.log(arr);               // [empty × 5]

const arr2 = [1,2,3,4,5];
delete arr2[2];
const result = arr2.map(x => 0);
console.log(result);            // [0,0,,0,0]

join(配列の要素を一つの文字列に連結する)

メソッド join
内容 配列の要素を一つの文字列に連結する
変換方法 関数内で指定
レスポンス 任意の値が返却される
補足 区切り文字は第一引数で指定する
(未指定(=デフォルト)の区切り文字は,
nullundefinedは空文字になる
const arr = [1,null,3,undefined,5,true,7,false,9,"Hello","World"];
let result = arr.join();
console.log(result);            // 1,,3,,5,true,7,false,9,Hello,World
result = arr.join("");
console.log(result);            // 135true7false9HelloWorld
result = arr.join(" ");
console.log(result);            // 1  3  5 true 7 false 9 Hello World
result = arr.join("--");
console.log(result);            // 1----3----5--true--7--false--9--Hello--World

参考文献