🌊

javascriptの配列を弄る

2023/12/30に公開

自分でアプリケーションを作ってみるにあたって、javascriptの知識がなさ過ぎたので
一旦javascriptを勉強している。

今回は配列について

まずは配列内の値に特定の計算処理をした上で、新しく配列を作る方法

//配列に特定の計算をして新しい配列を作る

const scores = [10, 20, 30]; //配列の要素全てに5点追加した配列を作る


const plusScores = [];  //新たな配列を定義

score.forEach((score) => { //forEachで配列scoresの要素をscoreとして回す
   plusScores.push(score + 5); //plusScoresという配列に回ってきたscoreに対してpushで5を足して格納する
});

//mapを使った記述 

const plusScores = scores.map((score) => {  //mapは配列の要素を1つずつ回して処理をした値をリターンして配列を作る 値を代入する配列を最初に指定しておく
    return score + 5;                     //配列の要素にしたいのはscoresの要素に+5した値なので return score + 5
});

次は配列内の特定の値だけを取り出して新しい配列を作る方法


//配列の中で特定の値を取り出して新しい配列を作る

const scores = [10, 20, 30];  //この配列の中から15以上の数値で新しい配列を作る

const scoresOver15 = [];    //15以上の数値を入れるための配列を定義

scores.forEach((score) => { //forEachで配列scoresの要素をscoreとして回す
    if(score >= 15) {       //もしscoreが15以上なら処理をする
        scoresOver15.push(score);   //先ほど定義した配列にscoreを代入
    }
});


//filterを使った記述

const scoresOver15 = scores.filter((score) => { //mapと違いfilterは元の要素を処理して元の要素数と同じ要素数を返すmapとは違い、元の要素を変更しないが条件に合致する要素だけを返す
    return score >= 15; //今回は15以上の数値だけを取り出し要素としたいので、 >= 15で15と同等もしくはそれ以上を指定する
}); 

次は配列の中身を分割代入を使って入れ替える方法

//定数の待避
//経路案内でスタートがSapporo、ゴールがHakodateだと仮定
let start = 'Sapporo';
let goal = 'Hakodate';


//復路案内を表示する際、スタートをHakodate、ゴールをSapporoにしたいときの記述を考える
start = goal ;
goal = start;

//実際の結果

start = Hakodate  //最初の start = goal の時 goalはHakodate なので startにはHakodateが代入される
goal = Hakodate //次の goal = start の時 startはHakodateになっているので、goalにはHakodateが代入される

//一時的な待避先を作り問題を解決する

let temp =''
temp = start;
start = goal;
goal = temp;

//実際の結果
temp = Sapporo
start = Hakodate
goal = Sapporo

//tempに経路でのstartであるSapporoを格納しておくことにより、startを上書きした後でもSapporoを使うことができるため問題が解決
//この際tempは待避させるために存在する値であり、実際の画面には表示させないことに注意する(必要に応じて表示させることも勿論できる)


//分割代入を使った記述

[goal, start] = [start, goal] //配列としてこのように記述すれば一括で処理が行われるので、待避を行わなくても上記と同じ結果になる

レスト構文とスプレッド構文について

//レスト構文

scores [1, 2, 3, 4, 5]; //この配列の一番最初の要素と残りの要素を別々の配列としたい

const[first] = scores; //これで一番最初の要素を取り出せばいいように見えるが、scoresの中身は変わっていない

const[first, ...others] = scores; //この記述なら配列firstにscoresの一番最初の要素1が代入され、配列othersに残りの2,3,4,5が代入される これをレスト構文と呼ぶ

//スプレッド構文

const scoresPlus = [6, 7]; //この配列の要素をscoresに追加したいとする

const scores = [1, 2, 3, 4, 5]; //元となる配列で、scoresPlusの要素をこの配列に追加したい

const scores = [1, 2, 3, 4, 5, scoresPlus] //単純に記述するとこれでよさそうだが、実際は[1, 2, 3, 4, 5, (6, 7)] このような形になってしまう

const scores = [1, 2, 3, 4, 5, ...scoresPlus] //このように表記することで[1, 2, 3, 4, 5, 6, 7]となる、これをスプレッド構文と呼ぶ またこのような記述をした場合でもレスト構文は使える

const [first, ...others] = scores; //上記コードのあとにこう記載した場合は配列firstに[1] 配列othersに[2, 3, 4, 5, 6, 7]となる

//レスト構文、スプレッド構文共に...を使って記載するので混合しがちだが、右辺で使われてる場合はスプレッド、左辺はレストと覚える。

分割代入をオブジェクトに使う場合

const scores = {
    Yamada: 100,
    Satou: 25,
    Itabashi: 77,
};
const {Yamada, Satou, Itabashi} = scores;   //配列であれば[]だったが、オブジェクトは{}なことに留意する必要がある

console.log(Yamada) //本来であれば console.log(scores['Yamada']) で呼び出さなければいけないが、分割代入でそれぞれのキーに定数名を与えているためYamadaで呼び出すことが出来る

//Yamadaだけのデータが欲しくて他はどうでもいい場合

const {Yamada} = score; //これだけでいいが、レスト構文を使って他は他で分けておくこともできる

const {Yamada,...others}; //これで他のデータはothersにオブジェクトのまま格納されている

スプレッド構文をオブジェクトに使う場合

//スプレッド構文をオブジェクトで使う

const scores = {
    Yamada: 100,
    Satou: 25,
    Itabashi: 77,
};

//上記の配列に以下の配列を追加したい場合

const scoresPlus = {
    Maruyama: 50
    Igarashi: 40
}

//スプレッド構文を使い以下のように記述

const scores = {
    Yamada: 100,
    Satou: 25,
    Itabashi: 77,
    ...scoresPlus,
};

最後にスプレッド構文を使って配列のバックアップを取る

const nums = [10, 20, 30]; // この配列のバックアップを取りたい
const numsBackup = nums; // バックアップを取る
nums[0] = 99; // numsの0番目の要素を99にして出力してみる
console.log(nums); //[99, 20, 30]を想定
console.log(numsBackup); //[10, 20, 30]を想定

//実際は両方[99,20,30]で表示される 何故か
//この時numsBackupがコピーするのはnumsの数値ではなく、numsの参照先をコピーしているので参照先の数値が変わると出力も変わってしまう
//配列、オブジェクトの場合はデータ量が多い場合も多くシステム負荷を考慮してこのような仕様になっている

//ではどうやってバックアップを取るのか


const nums = [10, 20, 30]; // バックアップを取りたい配列
const numsBackup = [...nums]; // numsの要素が空の配列に全て追加されるので、同じ要素をもった配列が生まれる = numsで作ったバックアップとは挙動が違うことに留意する

Discussion