配列処理の問題集

公開:2020/10/03
更新:2020/12/04
13 min読了の目安(約12300字TECH技術記事

はじめに

配列処理による問題またその解答をこの記事に書き残します。またコードはTypeScriptで書いています。問題は随時追加予定です!

(追記)
2020/11/14 問題㉑
2020/11/15 問題㉒
2020/11/30 問題㉓


問題①

1から100まで格納された配列の作成して下さい。

解答

const arry = [...new Array(101 - 1).keys()].map((n) => n + 1);
//[...new Array(101 - 1).keys()]だけだと0~99までの配列となるため、mapメソッドで調整

//別解
const array = Array.from({ length: 100 }, (_, i) => i + 1);
//Array.from(arrayLike,mapFn)
//arryLike(配列に変換する配列風オブジェクトまたは反復可能オブジェクト)
//mapFn(配列のすべての要素に対して呼び出される Map 関数。)

問題②

次の連想配列(images)のheightだけを取得し、新しい配列(heights)を作成して下さい。

type Images = {
  height: string;
  width: string;
}[];

const images: Images = [
  { height: "20px", width: "40px" },
  { height: "34px", width: "56px" },
  { height: "28px", width: "64px" },
];

解答

const heights = images.map(({ height }) => {//オブジェクトの分割代入の利用
  return height;
});

//省略記法
const heights = images.map(({ height }) => height);


//別解
const heights = images.reduce((acc, cur, i) => {
  acc[i] = cur.height;
  return acc;
}, []);

問題③

次の連想配列(member)の中から名前(name)の値だけを抜き取った配列が返るような関数getNameを作成して下さい。

type Members = {
  name: string;
  age: number;
  gender: "male" | "female";
}[];

const members: Members = [
  { name: "松井", age: 39, gender: "male" },
  { name: "今田", age: 34, gender: "female" },
  { name: "鈴木", age: 24, gender: "male" },
  { name: "山田", age: 56, gender: "male" },
  { name: "田中", age: 89, gender: "female" },
];

解答

type GetName<T extends Members, U> = (array: T) => U[];

const getName: GetName<Members, string> = (array) => {
  return array.map(({ name }) => name);
};
console.log(getName(members));
//["松井", "今田", "鈴木", "山田", "田中"]

問題④

以下の連想配列(users)の中から、管理者権限(admin)を持っている(true)ユーザーに絞り込み、filteredUsersという変数に格納して下さい。

type Users = {
  id: number;
  admin: Boolean;
}[];

const users: Users = [
  { id: 1, admin: true },
  { id: 2, admin: true },
  { id: 3, admin: false },
  { id: 4, admin: true },
  { id: 5, admin: false },
];

解答

const filteredUsers = users.filter(({ admin }) => admin);

問題⑤

次の多次元配列のインデックス0番目のみを取り出した配列を作成して下さい。

const array = [
  ["Ruffy", "captain"],
  ["Zoro", "combatant"],
];

解答

const arry = array.map((key) => key[0]);
console.log(arry); //"Ruffy", "Zoro"]

問題⑥

次の多次元配列の0番目の配列のみを取り出し新しい配列に作成して下さい。

const array = [
  ["Ruffy", "captain"],
  ["Zoro", "combatant"],
];

解答

const arr = array.filter((key, i) => {
  if (i === 0) {
    return key;
  }
});
console.log(arr); //["Ruffy", "captain"]

問題⑦

次の連想配列(member)の中から35歳以上の名前(name)の値だけを抜き取った配列が返るような関数getNameOver35を作成して下さい。

type Members = {
  name: string;
  age: number;
  gender: "male" | "female";
}[];

const members: Members = [
  { name: "松井", age: 39, gender: "male" },
  { name: "今田", age: 34, gender: "female" },
  { name: "鈴木", age: 24, gender: "male" },
  { name: "山田", age: 56, gender: "male" },
  { name: "田中", age: 89, gender: "female" },
];

解答

type GetNameOver35<T extends Members, U> = (array: T) => U[];

const getNameOver35: GetNameOver35<Members, string> = (array) => {
  return array.filter(({ age }) => age > 35).map(({ name }) => name);
};
console.log(getNameOver35(members));
//["松井", "山田", "田中"]

問題⑧

以下のような重複値を含む配列arrの中から、重複値を除く互いに素な配列を作成して下さい。

const arr = [2, 4, 7, 5, 4];

解答

const coprimeArr = [...new Set(arr)];//[2, 4, 7, 5]

//別解const coprimeArr = arr.filter((num, i, arrr) => {
  return arrr.indexOf(num) === i;
});//[2, 4, 7, 5]

問題⑨

次の連想配列の中からnameプロパティをもったユーザーに絞り込み、getNameという変数に格納して下さい。

interface User {
  id: number;
  name?: string;
}

const users: User[] = [
  { id: 1, name: "豊臣" },
  { id: 2 },
  { id: 3, name: "織田" },
];

解答

const getName = users
  .filter((user: User) => "name" in user)
  .map((user) => user);
  
  //別解
  const getName = users.filter(({ name }) => name).map((user) => user);

問題⑩

以下の連想配列(users)の中から、管理者権限(admin)を持っている(true)ユーザーを探し、最初に見つけた(true)ユーザーをadminという変数に格納して下さい。

type Users = {
  id: number;
  admin: Boolean;
}[];

const users: Users = [
  { id: 1, admin: false },
  { id: 2, admin: true },
  { id: 3, admin: false },
  { id: 4, admin: true },
  
];

解答

const admin = users.find(({ admin }) => admin);

問題⑪

次の連想配列(member)の中から,田中さんのオブジェクトを抽出するfindTanakaという関数,変数を作成しなさい。

type Members = {
  name: string;
  age: number;
  gender: "male" | "female";
}[];

const members: Members = [
  { name: "松井", age: 39, gender: "male" },
  { name: "今田", age: 34, gender: "female" },
  { name: "鈴木", age: 24, gender: "male" },
  { name: "山田", age: 56, gender: "male" },
  { name: "田中", age: 89, gender: "female" },
];

解答

const findTanaka = (array: Members) => {
  return array.find(({ name }) => name === "田中");
};
console.log(findTanaka(members));

//別解
const findTanaka = members.members.slice(-1)[0]; 

問題⑫

アンケートを実施した結果がusersという連想配列に格納されています。ユーザー全員が回答済みかどうかを確認し、hasSubmitted変数に結果(trueかfalse)を格納して下さい。

type Users = {
  id: number;
  hasSubmitted: Boolean;
}[];

const users: Users = [
  { id: 2, hasSubmitted: true },
  { id: 3, hasSubmitted: false },
  { id: 4, hasSubmitted: true },
];

解答

const hasSubmitted = users.every(({ hasSubmitted }) => hasSubmitted);

問題⑬

次のtripという連想配列に格納されたdistanceの合計を求めて、totalDistanceという変数に格納して下さい。

type Trips = { distance: number }[];

const trips: Trips = [{ distance: 34 }, { distance: 12 }, { distance: 1 }];

解答

const totalDistance = trips.reduce((sum, trip) => {
  return trip.distance + sum;
}, 0);
console.log(totalDistance);//47

//分割代入
const totalDistance = trips.reduce((sum, { distance }) => {
  return distance + sum;
}, 0);
console.log(totalDistance); //47

問題⑭

次の変数engineersに格納されたエンジニアの種類(フロントエンド、バックエンド)の数を種類を集計し、一つのオブジェクトに格納して下さい。

type Engineers = { type: "Frontend" | "Backend" }[];

const engineers: Engineers = [
  { type: "Frontend" },
  { type: "Backend" },
  { type: "Backend" },
  { type: "Frontend" },
  { type: "Frontend" },
  { type: "Backend" },
  { type: "Backend" },
];

解答

const engType = engineers.reduce(
  (sum, { type }) => {
    if (type === "Frontend") {
      sum.Frontend++;
    } else {
      sum.Backend++;
    }
    return sum;
  },
  { Frontend: 0, Backend: 0 }
);
console.log(engType);//{Frontend: 3, Backend: 4}

問題⑮

次の変数objを連想配列[{A:'a'},{B:'b'}]にして下さい。

const obj = {
  a: "A",
  b: "B",
};

解答

const arr = Object.entries(obj).map((key) => {
  return { [key[1]]: key[0] };
});

問題⑯

次の変数arrをオブジェクト{a:"0", b:"1"}にして下さい。

const arr = ["a", "b"];

解答

type Alpha = {
  [alpha: string]: string;
};const obj:Alpha = arr.reduce((prev, curr, i) => {
  return { ...prev, [curr]: `${i}` };
}, {});//引数のprevの挙動をコンソール上で確認すると理解が深まります!


//別解(tsconfig内"noImplicitAny": falseと設定する必要があります)
type Alpha = {
  [alpha: string]: string;
};

const obj: Alpha = arr.reduce((ob, data, i) => {
  ob[data] = i;
  return ob;
}, {});


問題⑰

次の変数fruitsの中から"みかん"、"ぶどう"をキーに持つオブジェクトのみを抽出し、新しい変数serectFruitsに格納して下さい。

type Fruitsobj = {
  price: number;
  num: number;
};
type Fruits = {
  [fruit: string]: Fruitsobj;
};

const fruits: Fruits = {
  みかん: { price: 200, num: 5 },
  いちご: { price: 400, num: 1 },
  ぶどう: { price: 380, num: 7 },
};

解答

const arr = Object.entries(fruits);
const arrr = arr.filter((key) => {
  return key[0] === "みかん" || key[0] === "ぶどう";
});
const selectFruits = arrr.reduce((prev, [k, v]) => {
  return { ...prev, [k]: v };
}, {});
//ぶどう: {price: 380, num: 7}
//みかん: {price: 200, num: 5}

問題⑱

次の配列の中で一番大きい値を求めて下さい。

const array = [40, 100, 300, 50];

解答

const result = array.reduce((acc, cur) => {
  return acc > cur ? acc : cur;
});//300

//別解(applyメソッドの利用)
const result1 = Math.max.apply(null, array);

//別解(スプレッド構文の利用)
const result2 = Math.max.(...array);

//別解
function result3(array: number[]) {
  let tempArr = array.sort((a, b) => {
    return a - b;
  });
  let largest = tempArr.pop();
  return largest;
}
console.log(result3(array));//300

問題⑲

次のJsonJson形式の変数complexJsonから"ハンバーグ"の要素だけ取り出し、配列でラップして下さい。

expect [ハンバーグ: {分類: "洋食", 主成分: "タンパク質"}]

type ComplexJson = {
  [food: string]: { 分類: string; 主成分: string | object };
};

const complexJson: ComplexJson = {
  ハンバーグ: {
    分類: "洋食",
    主成分: "タンパク質",
  },
  カレー: {
    分類: "洋食",
    主成分: {
      ルー: "タンパク質",
      ライス: "炭水化物",
    },
  },
  親子丼: {
    分類: "和食",
    主成分: {: "タンパク質",
      ご飯: "炭水化物",
    },
  },
};

解答

const arr = keyarray.reduce((acc, cur) => {
  if (cur[0] === "ハンバーグ") {
    return [{ ...acc, [cur[0]]: cur[1] }];
  }
  return acc;
}, []);

問題⑳

次の連想配列のオブジェクトのキー名を"0"→"id"、"1"→"shop"に変更して下さい。

const srcData = [
  { 0: "id1", 1: "店A" },
  { 0: "id2", 1: "店B" },
  { 0: "id3", 1: "店C" },
];

解答

const newSrcData = srcData.map((obj) => {
  obj.id = obj[0];
  obj.shop = obj[1];
  delete obj[0], delete obj[1];
  return obj;
});

問題㉑

次の連想配列の果物の詳細が書かれた各オブジェクトから'totalItems'(個数の合計),'cartTotal'(合計金額)をプロパティにもつオブジェクトを作成してください。

type Cart = {
  item: string;
  price: number;
  amount: number;
}[];
const cart: Cart = [
  {
    item: 'いちご',
    price: 150,
    amount: 3,
  },
  {
    item: 'みかん',
    price: 250,
    amount: 3,
  },
  {
    item: 'ぶどう',
    price: 300,
    amount: 2,
  },
];

解答

const total = cart.reduce(
  (total, cartItem) => {
    const { amount, price } = cartItem;
    total.totalItems += amount;
    total.cartTotal += price;
    return total;
  },
  {
    totalItems: 0,
    cartTotal: 0,
  }
);
console.log(total);//{cartTotal: 700,totalItems: 8}


問題㉒

次の1~30までの数字が格納された配列'item'を10分割、14分割した二次元配列'newItems1','newItems2'を作成してください。

const item = Array.from({ length: 30 }, (_, index) => {
  return index + 1;
});

解答

const itemPerPage1 = 10;
const itemPerPage2 = 14;

const pages = (itemPer: number) => {
  return Math.ceil(item.length / itemPer);
};

const newItems1 = Array.from({ length: pages(itemPerPage1) }, (_, index) => {
  const start = index * itemPerPage1;
  const tempItems = item.slice(start, start + itemPerPage1);

  return tempItems;
});

const newItems2 = Array.from({ length: pages(itemPerPage2) }, (_, index) => {
  const start = index * itemPerPage2;
  const tempItems = item.slice(start, start + itemPerPage2);

  return tempItems;
});

console.log(newItems1);//[ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ], [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 ] ] 
console.log(newItems2);//[ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ], [ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 ], [ 29, 30 ] ] 


問題㉓

次の連想配列(member)の中から,鈴木さんを同僚、松井さんと今田さんを後輩として関係を区別してください。

​​type Members = {
  name: string;
  age: number;
  gender: "male" | "female";
}[];

const members: Members = [
  { name: "松井", age: 21, gender: "male" },
  { name: "今田", age: 23, gender: "female" },
  { name: "鈴木", age: 27, gender: "male" },
  { name: "山田", age: 33, gender: "male" },
  { name: "田中", age: 35, gender: "female" },
];

for (let i = 0; i < members.length; i++) {
  const element = members[i];
  if (element['name'] === '鈴木') {
    console.log(`${element['name']} is my colleague`);//鈴木 is my colleague
    break;//continueであれば山田さん、田中さんのオブジェクトが取れる。
  }
  console.log(`${element['name']} is my junior coworker`);
  //松井 is my junior coworker 
  //今田 is my junior coworker 
}