書く機会の多いものなら、スラスラ書ける方がいいので、毎日の練習と思ってここに書き溜めておきます。
Case 1...オブジェクトのKeyだけ配列にしたい
ObjectのKeyだけの配列を取り出したい時
const members = {
lerder: "tom",
member: "sam"
};
// この変数に格納して console.log してください
const roles
console.log(roles);
Answer 1
const roles = Object.keys(members)
console.log(roles); // => ["lerder", "member"]
Case 2...Array Object と Mapメソッド
大学学年別の所属メンバーの1年生(freshman)だけ、敬称した名前だけ配列に格納したい時。
// 大学の学年別の所属メンバー
const members = {
freshman: ["佐藤", "加藤", "伊藤"],
junior: ["岡田", "前田", "上田"]
};
// 名前に様つける関数
const addHonorificTitle = name => {
return `${name}様`;
};
// この変数に格納して console.log してください
const names;
console.log(names);
Answer 2
const names = members.freshman.map(member => addHonorificTitle(member));
console.log(names); // => ["佐藤様", "加藤様", "伊藤様"]
できたら、省略して書きたい。
map
のコールバック関数内は引数と、何かの関数内の引数が同じな場合は省略できる。
const names = members.freshman.map(addHonorificTitle);
console.log(names); // => ["佐藤様", "加藤様", "伊藤様"]
Case 3...forEach
三角形の底辺と高さのオブジェクトの集合を配列にしたデータ(Array in Object)がtriangles
という変数名に格納されています。
このデータの中に各三角形の面積(底辺×高さ÷2)の結果をareas
変数名を追加する処理を書いてください。
const triangles = [
{ base: 10, height: 10 },
{ base: 20, height: 20 },
{ base: 30, height: 30 }
];
// 何かの処理
console.log(triangles)
Answer 3
triangles.forEach((triangle) => {
triangle.areas = (triangle.base * triangle.height) / 2
});
// [Object, Object, Object]
// 0: Object
// base: 10, height: 10, areas: 50
// 1: Object
// base: 20, height: 20, areas: 200
// 2: Object
// base: 30, height: 30, areas: 450
色々な方法で実装が可能だとは思いますが、なぜforEach
を使用したかの説明をします。
forEach
は戻り値を持たないので、何かの処理を実現しようとすると外部スコープに対する操作が前提になります。文脈次第ですが、変数triangles
に三角形の合計であるareas
のデータが追加されても致命的なエラーは起こしにくいのではと考えてこう実装しました。ただし、基本的には外部スコープのデータを書き換えてしまうので、注意は必要です。
参考
Case 4...pluck
Railsのメソッドpluck
にあるような関数を作ってください。
仕様
- とる引数は2つ(arrayObject, objectのプロパティ名)
- objectのvalue一覧を新たな配列で返す
const memberObjects = [
{ id: 1, name: "田中" },
{ id: 2, name: "中村" },
{ id: 3, name: "村山" },
{ id: 4, name: "山川" },
{ id: 5, name: "川本" }
];
const pluck = // 要件を満たすような関数を作成してください;
const memberNames = pluck(memberObjects, "name");
console.log(memberNames); // => ["田中", "中村", "村山", "山川", "川本"]
Answer 3
const memberObjects = [
{ id: 1, name: "田中" },
{ id: 2, name: "中村" },
{ id: 3, name: "村山" },
{ id: 4, name: "山川" },
{ id: 5, name: "川本" }
];
const pluck = (arrayObject, propertyName) => {
return arrayObject.map(object => object[propertyName]);
};
const memberNames = pluck(memberObjects, "name");
console.log(memberNames); // => ["田中", "中村", "村山", "山川", "川本"]
console.log(memberObjects); // => 元の状態のままです
map
の特徴の1つとして、イミュータブルなところがあります。イミュータブルとは、オブジェクトの状態が変わらないことを意味します。イミュータブルなコーディングが意識されたプロジェクトの利点は、データの状態や挙動の見通しが良くなる点が挙げられます。つまり、データは作成されたときのままであることが保証されます。
map
は、元の配列を書き換えず別の新たな配列を作成するので、イミュータブルな処理をすることができます。
Case 5...分割代入とその参照
下記のオブジェクトのプロパティname
だけ分割代入したいとき
const memberObjects = { id: 1, name: "川本" };
Answer 5
const { name } = memberObjects;
console.log(name);
(注意)プロパティの名前を変数の名前は一致させる必要があります。
では、name
でなく、memberName
という変数名に代入したい場合は?どう書けばいいでしょうか?
const { name: memberName } = memberObjects;
console.log(memberName); // => 川本
Case 6...オブジェクトの参照
object.value
の値をminus
関数を用いて-1
したいとします。
しかし、値は変わりません(10
)でした。どうすれば値を変更(9
に)できるでしょうか?
let object = { value: 10 };
const minus = ({ value }, val) => (value = value - val);
minus(object, 1);
console.log(object.value); // => 10
問題点、minus
関数の第一引数に変数代入している時点で、最初に宣言したobject.value
とは別のメモリ格納先の値になっています。
Answer 6
問題点に指摘した通りで、解決方法は、1行目で宣言した値を参照するようにする。
let object = { value: 10 };
const minus = ({ value }, val) => (object.value = value - val);
minus(object, 1);
console.log(object.value); // => 9
Case 7...オブジェクトの参照と等価
through
関数を通して格納されたobject2
とobject
は等価(厳密比較してtrue
になる)でしょうか?
let object = { value: 10 };
const through = (object) => object;
const object2 = through(object);
console.log(object === object2); // true OR false
Answer 7
答え true
理由 object
と object2
は同じ参照先なので(プロミティブ型では値の比較で、オブジェクトでは参照の比較なので)。
Case 8...ビートルズのアルバムだけ抜き出したい
以下のようなデータがあるとします。albumTitles
には、ビートルズのアルバムのタイトルもあれば、マイケルジャクソンやスティービーワンダーのも混じっています。これを albumTitles
は配列なので filter
を使って、ビートルズのアルバムのタイトルだけのArrayObjectを作ってください。
const artist = { id: 1, name: "beatles" };
const albumTitles = [
{ artistId: 1, name: "Revolver" },
{ artistId: 1, name: "Sgt. Pepper's Lonely Hearts Club Band" },
{ artistId: 1, name: "Magical Mystery Tour" },
{ artistId: 2, name: "Innervisions" },
{ artistId: 2, name: "Key of Life" },
{ artistId: 3, name: "Thriller" },
{ artistId: 3, name: "Bad" },
{ artistId: 3, name: "Invincible" }
];
// この変数に格納して console.log してください
const selectAtistAlbums
const result = selectAtistAlbums();
console.log(result);
Answer 8
const selectAtistAlbums = ({ id: artistIdParam }, albumTitles) => {
return albumTitles.filter(({ artistId }) => artistId === artistIdParam);
};
const result = selectAtistAlbums(artist, albumTitles);
console.log(result); // => [Object, Object, Object]
//
// 0: Object
// artistId: 1
// name: "Revolver"
// 1: Object
// artistId: 1
// name: "Sgt. Pepper's Lonely Hearts Club Band"
// 2: Object
// artistId: 1
// name: "Magical Mystery Tour"
ビートルズのアルバムだけ抜き出せましたね。
Case 9...reduceの練習(1)
ここからは、reduce
の練習です。配列操作系の万能メソッド reduce
を使って、配列 numbers
の値を1つづつ足してください。引数名はなんでもいいです。
const numbers = [1, 2, 3];
// この変数に格納して console.log してください
const result;
console.log(result);
Answer 9
const numbers = [1, 2, 3];
const result = numbers.reduce((accumlator, currentValue) => {
return accumlator + currentValue;
}, 0);
console.log(result); // => 6
Case 10...reduceの練習(2)
またreduce
の練習です。 reduce
を使って、配列 numbers
にある数値の中で最大値を返すアロー関数を作成してください。引数名はなんでもいいです。
const numbers = [1, 10, 300, 100, 20];
// この変数に格納して console.log してください
const result;
console.log(result);
Answer 10
const numbers = [1, 10, 300, 100, 20];
// この変数に格納して console.log してください
const result = numbers.reduce((previousValue, currentValue) => {
if (previousValue < currentValue) {
return currentValue;
} else {
return previousValue;
}
});
console.log(result);
reduce
第二引数が指定されていない場合、numbers
の一番最初の関数実行時のpreviousValueが第二引数の初期値になる。
Case 11...reduceの練習(3)
またreduce
の練習です。 reduce
を使って、以下のArrayObjectが格納されている変数types
の各要素のプロパティtype毎のカウント数をObjectとして返す関数をresult
に格納してください。引数名はなんでもいいです。
const types = [ { type: "A" },{ type: "B" },{ type: "B" },{ type: "B" },{ type: "C" },{ type: "C" } ];
// この変数に格納して console.log してください
const result;
console.log(result);
Answer 11
const types = [ { type: "A" },{ type: "B" },{ type: "B" },{ type: "B" },{ type: "C" },{ type: "C" } ];
// この変数に格納して console.log してください
const result = types.reduce(
(accumlator, current) => {
if (current.type === "A") accumlator.typeA++;
if (current.type === "B") accumlator.typeB++;
if (current.type === "C") accumlator.typeC++;
return accumlator;
},
{ typeA: 0, typeB: 0, typeC: 0 }
);
console.log(result);