見出し画像

JavaScript_配列操作のメソッド① #269日目

今日から冒頭に一言日記を付けてみようかなと思います。

【一言日記】
昨日体調を崩していた長男が一日で復活!食あたりだったのかな。今日はばぁば宅に遊びに行って大はしゃぎしてました。


さて、Progateを中心に学んだJavaScriptのメソッドについてです。
JavaScriptでの配列は以下のように記述できます。Pythonで言うところのリストですね。

const animals = ["dog", "cat", "sheep"];

この配列の後ろに「配列.オプション」とすることで、様々な操作をすることが可能です。


pushメソッド

配列の最後に要素を追加できるメソッドです。

const characters = ["いぬ", "ねこ", "ひつじ"];

console.log(characters);

// 配列charactersに文字列「とり」を追加
characters.push("とり");


console.log(characters);
 
// 出力結果
[ 'いぬ', 'ねこ', 'ひつじ', 'とり' ]

一番最後に要素が追加されています。


forEachメソッド

配列の中の要素を1つずつ取り出して、その全てに同じ処理を実行するメソッドです。

const characters = ['いぬ', 'ねこ', 'ひつじ', 'とり'];

// 配列charactersの中身をすべて出力
characters.forEach((character) => {
  console.log(character);
});


// 出力結果
いぬ
ねこ
ひつじ
とり

全ての要素に「出力する」という処理を実行しています。また、forEachメソッドは処理を実行するだけのため、戻り値を持たないという特徴があります。

return文を定義しても「undefined」と返って来てしまいます。


findメソッド

配列の要素を、順番に引数として渡して処理を実行します。最終的にreturn文に条件式を定義し、その条件に合う最初の要素のみを取り出すメソッドです。

const numbers = [1, 3, 5, 7, 9];

// 配列numbersから3の倍数を見つけ、定数foundNumberに代入
const foundNumber = numbers.find((number) => {
  return number%3 === 0;
});


console.log(foundNumber);

// 出力結果
3

オブジェクトでも同様に使用できます。

const characters = [
  {id: 1, name: "いぬ", age: 5},
  {id: 2, name: "ねこ", age: 3},
  {id: 3, name: "ひつじ", age: 30},
  {id: 4, name: "とり", age: 10}
];

// idが3のオブジェクトを見つけ、定数foundCharacterに代入
const foundCharacter = characters.find((character) => {
  return character.id === 3;
});


console.log(foundCharacter);

// 出力結果
{ id: 3, name: 'ひつじ仙人', age: 30 }


filterメソッド

配列の要素を、順番に引数として渡して処理を実行します。最終的にreturn文に条件式を定義し、その条件に合う全ての要素を取り出すメソッドです。結果は新たな配列として抽出されてきます。

const numbers = [1, 2, 3, 4];

// numbersから偶数を全て取り出し、定数evenNumbersに代入
const evenNumbers = numbers.filter((number) => {
  return number%2 === 0;
});


console.log(evenNumbers);

// 出力結果
[ 2, 4 ]

オブジェクトでも同様に使用できます。

const characters = [
  {id: 1, name:"いぬ", age: 10},
  {id: 2, name:"ねこ", age: 6},
  {id: 3, name:"ひつじ", age: 60}
];

// 20歳未満のキャラクターを全て取り出し、定数underTwentyに代入
const underTwenty = characters.filter((character) => {
  return character.age < 20;
});


console.log(underTwenty);

// 出力結果
[ { id: 1, name: 'にんじゃわんこ', age: 14 },
  { id: 2, name: 'ベイビーわんこ', age: 5 } ]


mapメソッド

配列内の全ての要素に処理を実行し、その戻り値から新たな配列を作成するメソッドです。

const numbers = [1, 2, 3, 4];

// 定数numbersの要素を2倍にした新たな配列をmapメソッドで作成
const doubledNumbers = numbers.map((number) => {
  return number*2;
});


console.log(doubledNumbers);
 
// 出力結果
[ 2, 4, 6, 8 ]

オブジェクトでも同様に使用できます。

const names = [
  {firstName: "Kate", lastName: "Jones"},
	{firstName: "John", lastName: "Smith"},
	{firstName: "Denis", lastName: "Williams"},
	{firstName: "David", lastName: "Black"}
];

// 定数namesの2つのプロパティを合体させた新たな配列をmapメソッドで作成
const fullNames = names.map((name) => {
  return name.firstName + name.lastName;
});


console.log(fullNames);
 
// 出力結果
[ 'KateJones', 'JohnSmith', 'DenisWilliams', 'DavidBlack' ]

forEachメソッドとの違いは、mapメソッドは戻り値を持つという点です。そのためreturn文を定義して新たな配列を作成することができます(forEachメソッドではundefinedになる)。


reduceメソッド

ある初期値に対して、配列の要素をそのまま、ないし処理を加えてから足し上げて、合計値を算出できるメソッドです。第一引数でコールバック関数を受け取り、第二引数で初期値を設定します。

配列.reduce((合計が累積する引数, 各要素を受け取る引数) => {
  処理内容;
  return 合計が累積する引数;
}, 初期値(数字) });

具体的に記述してみます。初期値「0」から、配列の要素が足しあがっていく処理を定義しています。

/// 1~10の数字配列
const nums = [
  1,2,3,4,5,6,7,8,9,10
]
 
/// それら合計値を計算
let total = nums.reduce((accum, x)=>{
  accum += x;
  return accum; 
}, 0);
 
console.log(total) 
// 出力結果
55

文字列を扱うこともできます。Fizz Buzzの中にzが何個あるか数える処理です。

const text = "Fizz Buzz"
 
const count = text.split('').reduce((num, ch)=>{
  if(ch === 'z'){ num++ } 
  return num
}, 0)
 
console.log(`'z' appears ${count} times`)
  /// => 'z' appears 4 times


sortメソッド

配列の要素を並び替えるメソッドです。文字列の昇順として並び替えるか、並び順を指定して並び替えるかができます。

まず文字列の昇順として並び替える方法です。引数に何も指定しなければいいだけです。配列が数字だった場合、数字を"文字列"として並び替えるため意図通りに並び変わらない可能性が高いので注意です。

配列名.sort()

やや複雑なのが、並び順を指定する方法です。配列の各要素を順番に比較し、その大小によって戻り値を振り分けることで並び順を定義します。まずはコードを見てみます。

const test = [1, 30, 25, 40];
test.sort((a, b) => {
  if (a > b) {
    return -1;
  } else if (a < b) {
    return 1;
  } else {
    return 0;
  }
});

console.log(test)


// 出力結果
[ 40, 30, 25, 1 ]

1などの「0より大きい数字」が戻ると、aとbのうちbが先に来ます。-1などの「0より小さい数字」が戻ると、aとbのうちaが先にきます。

・コールバック関数が 0 未満の値(例えば -1 )を返した場合、一つ目の要素を二つ目の要素より小さいインデックスにする
・コールバック関数が 0 を返した場合はそのまま
・コールバック関数が 0 より大きい値(例えば 1 )を返した場合、二つ目の要素を一つ目の要素より小さいインデックスにする

https://www.javadrive.jp/javascript/array/index16.html

個人的な覚え方ですが、-1で一つ目が先、1で二つ目が先、なので、どっちも線が3つ揃う、と覚えました(マイナス記号を一つの線として)。笑


関数の動きを確認するため、各所で出力してみます。配列の全ての組み合わせを比較して順番を振っていることが分かります。

const test = [1, 30, 25, 40];
test.sort((a, b) =>{
  console.log(a + "と" + b);
  if (a > b) {
    console.log("return -1");
    return -1;
  } else if (a < b) {
    console.log("return -1");
    return 1;
  } else {
    console.log("return 0");
    return 0;
  }
});
console.log(test)


// 出力結果

130
return -1
125
return -1
3025
return -1
140
return -1
2540
return -1
3040
return -1
[ 40, 30, 25, 1 ]

ちなみに戻り値は-1や1じゃなくても、0か、0より大きいか小さいかであれば問題ありません。

つまり、わざわざ-1や1に直さなくても、単純にa - bを戻り値に設定するだけでも大小比較になるのでOKです。

ここまでお読みいただきありがとうございました!!


参考


この記事が気に入ったらサポートをしてみませんか?