4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptの連想配列の説明をしつつ、配列内文字列の出現回数を調べる

Posted at

前段

A氏「数字が入っているリストがあって、そこから数字の出現回数を調べたいんですけど、連想配列使わない方法ってないですか?」
私 「連想配列じゃダメなのですか?」
A氏「いまいち連想配列が分からないので、可能なら避けて通りたい…」
私 「(他の方法かぁ。ん? でも、これは連想配列を理解するにはいい題材なのでは? 避けて通らない方が!)」

その時に説明した内容を資料にまとめることになりました。

配列と連想配列

ともあれ、この記事をご覧の方の中には配列と連想配列の違いから、という方もいると思うので簡単に説明。

配列は0から始まる数字(インデックス)を指定して作業を行う。

sample.ts
const list: string[] = [
  "れもん",
  "みかん",
  "りんご"
];
console.log(list[0]); // れもん
console.log(list[1]); // みかん
console.log(list[2]); // りんご

連想配列は数字(インデックス)ではなく文字列を指定して作業を行う。

sample.ts
const map: {[key:string]:string} = {
  "lemon":"れもん",
  "orange":"みかん",
  "apple":"りんご"
};
console.log(map["lemon"]); // れもん
console.log(map["orange"]); // みかん
console.log(map["apple"]); // りんご

ストーリー

買い物にいったお母さんが果物をたくさん買って帰ってきました。
スーパーの袋に手を突っ込み、無造作に机の上に並べます。
連想配列_2.png

sample.ts
const fruitList: string[] = [
	"れもん",
	"みかん",
	"りんご",
	"みかん",
	"りんご",
	"れもん",
	"みかん",
	"りんご",
	"みかん",
	"みかん",
	"ぶどう"
];

そこに子供がやってきました。

子供「1番目の果物は"れもん"だね」

sample.ts
// 1番目(先頭)の要素にアクセスするための数字は0です。
console.log(fruitList[0]); // れもん

母親「そうね。それじゃあ、まず、各果物をまとめましょう」

sample.ts
// 連想配列
const note: { [key: string]: number } = {};

// フルーツリストの数だけ繰り返す
for ( let i = 0; i < fruitList.length; i++ ) {
	// フルーツ(の名前)取得
	const fruit = fruitList[ i ];

	// 連想配列に登録されているかどうか
	if ( note[ fruit ] == null ) {
		// 連想配列に登録されていなかったら1を設定
		note[ fruit ] = 1;
		continue;
	}

	// 連想配列に登録されていたら、登録内容をインクリメント
	note[ fruit ] = note[ fruit ] + 1;
}

子供「訳が分からないよ」
母親「順番に見ていけば分かるわ」
子供「がんばる」
母親「最初のフルーツ(fruitList[0])は"れもん"だったわね。noteには"れもん"というタイトルをつけたメモを貼り付けて、そこに「正」の字でカウントしましょうか。"れもん"が1つ」

連想配列_3.png

母親「次のフルーツ(fruitList[1])は"みかん"。noteに"みかん"はないから、またメモを貼り付けるわね」

連想配列_4.png

母親「次のフルーツ(fruitList[2])は"りんご"。これもnoteにメモを貼り付ける」

連想配列_5.png

母親「次のフルーツ(fruitList[3])は"みかん"。あ、noteに"みかん"があるじゃないの。それなら「正」の字の縦線を書くわね。これを繰り返して…」

連想配列_6.png

母親「ふぅ、全部で11個もフルーツを買っていたのね。でも、これで分類が終わったわ」

連想配列_7.png

子供「一番たくさんあったのは、どれかな?」
母親「まず、タイトルを抜き出して並べてみましょうか」

連想配列_8.png
sample.ts
const memoTitleList = Object.keys( note );

母親「これを順番に比較していくわ。例えば、"れもん"と"みかん"ならどちらが大きいかしら?」
子供「"みかん"!」
母親「正解よ。それじゃ、その繰り返しで、一番たくさん入っていたのは何か調べましょう」
子供「がんばる」

sample.ts
// 初期値
let maxNum = 0;
let maxNumFruit = "";

// 連想配列noteの、key値の配列を取得
const memoTitleList = Object.keys( note );

// memoTitleListの数だけ繰り返す
for ( let i = 0; i < memoTitleList.length; i++ ) {
	const memoTitle = memoTitleList[ i ];

	// 連想配列noteにkey値であるmemoTitle(果物の名前)を与えて、value(正の字の数)を得る
	const fruitCount = note[ memoTitle ];

	// 保持しておいた最大数と比較
	if ( maxNum > fruitCount ) {
		// value(正の字で数えた数)が最大値より小さい場合はcontinue
		continue;
	}
	// 最大数とその果物名を保持
	maxNum = fruitCount;
	maxNumFruit = memoTitle;
}

console.log( maxNum ); // 5
console.log( maxNumFruit ); // みかん

子供「一番たくさん買ったのは、"みかん"だ!」
母親「うちの子、天才(涙)」

コード

ストーリーで使ったもの

sample.ts
const fruitList: string[] = [
	"れもん",
	"みかん",
	"りんご",
	"みかん",
	"りんご",
	"れもん",
	"みかん",
	"りんご",
	"みかん",
	"みかん",
	"ぶどう"
];

// 連想配列
const note: { [key: string]: number } = {};

// フルーツリストの数だけ繰り返す
for ( let i = 0; i < fruitList.length; i++ ) {
	// フルーツ(の名前)取得
	const fruit = fruitList[ i ];

	// 連想配列に登録されているかどうか
	if ( note[ fruit ] == null ) {
		// 連想配列に登録されていなかったら1を設定
		note[ fruit ] = 1;
		continue;
	}

	// 連想配列に登録されていたら、登録内容をインクリメント
	note[ fruit ] = note[ fruit ] + 1;
}

// 初期値
let maxNum = 0;
let maxNumFruit = "";

// 連想配列noteの、key値の配列を取得
const memoTitleList = Object.keys( note );

// memoTitleListの数だけ繰り返す
for ( let i = 0; i < memoTitleList.length; i++ ) {
	const memoTitle = memoTitleList[ i ];

	// 連想配列noteにkey値であるmemoTitle(果物の名前)を与えて、value(正の字の数)を得る
	const fruitCount = note[ memoTitle ];

	// 保持しておいた最大数と比較
	if ( maxNum > fruitCount ) {
		// value(正の字で数えた数)が最大値より小さい場合はcontinue
		continue;
	}
	// 最大数とその果物名を保持
	maxNum = fruitCount;
	maxNumFruit = memoTitle;
}

console.log( maxNum ); // 5
console.log( maxNumFruit ); // みかん

整理版

sample2.ts
const fruitList: string[] = [
	"れもん",
	"みかん",
	"りんご",
	"みかん",
	"りんご",
	"れもん",
	"みかん",
	"りんご",
	"みかん",
	"みかん",
	"ぶどう"
];

const note: { [key: string]: number } = {};

let maxNum = 0;
let maxNumFruit = "";

const len = fruitList.length;
for ( let i = 0; i < len; i++ ) {
	const fruit = fruitList[ i ];
	let fruitCount = note[ fruit ] == null ? 1 : note[ fruit ] + 1;
	note[ fruit ] = fruitCount;

	if ( maxNum > fruitCount ) {
		continue;
	}
	maxNum = fruitCount;
	maxNumFruit = fruit;
}

console.log( maxNum ); // 5
console.log( maxNumFruit ); // みかん

補足

  • Object.keysでとれる順番は、画像のように「れもん-みかん-りんご-ぶどう」とは限りません。
  • コードはTypeScriptで書いてますが、型部分を消せばjsとしても使える、と思います。(ただし、検証はしていない)

素材

いらすとやさんの素材を使わせていただきました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?