概要
文系(体育科)卒業の僕が、人並みのアルゴリズムを身につけるためにLeetCodeを初めてみました。
日本だとAtCoderが一般的なようですが、海外エンジニアへの憧れを持つ僕はLeetCodeを選びました。
フロントの言語しかほぼ触ったことがないのでJavaScriptでやっていこうと思います。
問題
2635. Apply Transform Over Each Element in Array
問題文
Given an integer array arr and a mapping function fn, return a new array with a transformation applied to each element.
The returned array should be created such that returnedArray[i] = fn(arr[i], i).
Please solve it without the built-in Array.map method.
初期コード
/**
* @param {number[]} arr
* @param {Function} fn
* @return {number[]}
*/
var map = function(arr, fn) {
};
あぁもう、パッと見が難しいよー。
整理してみます。
- 整数の配列
arr
-
fn
はmapping関数 - 各要素を変換して新しい配列をreturnする
- 新しい配列は
returnedArray[i] = fn(arr[i],i)
のように作られる - mapping関数は使ってはいけない
- 新しい配列は
よくわからないので例文から紐解いてみる作戦でいきます。
📝Example1
Input: arr = [1,2,3], fn = function plusone(n) { return n + 1; }
Output: [2,3,4]
Explanation:
const newArray = map(arr, plusone); // [2,3,4]
The function increases each value in the array by one.
-
arr
に[1,2,3] -
plusone(n)
は引数nに+1を返す関数
📝Example2
Input: arr = [1,2,3], fn = function plusI(n, i) { return n + i; }
Output: [1,3,5]
Explanation: The function increases each value by the index it resides in.
-
arr
に[1,2,3] - plusIは配列の値とindexの値が入る
- 1回目 1 + 0 = 1
- 2回目 2 + 1 = 3
- 1回目 3 + 2 = 5
📝Example3
Input: arr = [10,20,30], fn = function constant() { return 42; }
Output: [42,42,42]
Explanation: The function always returns 42.
- arrに[10,20,30]
- 常に42を返す
まずは最終的にreturnされるのは入れるなので配列をreturnするようにしてみます。
fn
は引数をnだけ1つ/nとiの2つ/何も受け取らないのケースがあるようです。
全てのケースを考慮して実装が必要そうです。
/**
* @param {number[]} arr
* @param {Function} fn
* @return {number[]}
*/
var map = function(arr, fn) {
const result = [];
// 処理が入る
return result;
};
次に、map関数を使わずに配列をループさせて、その要素とインデックスの値をfn関数に渡します。
forまたforEachでいいと思うのでそれでいこう。
/**
* @param {number[]} arr
* @param {Function} fn
* @return {number[]}
*/
var map = function(arr, fn) {
const result = [];
for (let i = 0; i < arr.length; i++) {
// 処理が入る
}
return result;
};
配列の各要素arr[i]
とその要素のインデックスi
を関数fn
に渡してみます。
fn
から返された値を新しい配列result
に追加します。
/**
* @param {number[]} arr
* @param {Function} fn
* @return {number[]}
*/
var map = function(arr, fn) {
const result = [];
for (let i=0; i<arr.length; i++) {
result.push(fn(arr[i],i))
}
return result;
};
こうしておけば、
📝Example1
Input: arr = [1,2,3], fn = function plusone(n) { return n + 1; }
Output: [2,3,4]
- i=0の時fn(arr[0])→plusone(1) → 1 + 1 = 2 → result = [2]
- i=1の時fn(arr[1])→plusone(2) → 2 + 1 = 3 → result = [2,3]
- i=2の時fn(arr[2])→plusone(3) → 3 + 1 = 4 → result = [2,3,4]
となり良さそうです。
📝Example2
Input: arr = [1,2,3], fn = function plusI(n, i) { return n + i; }
Output: [1,3,5]
- i=0の時fn(arr[0])→plusI(1,0) → 1 + 0 = 1 → result = [1]
- i=1の時fn(arr[1])→plusI(2,1) → 2 + 1 = 3 → result = [1,3]
- i=2の時fn(arr[2])→plusI(3,2) → 3 + 2 = 5 → result = [1,3,5]
となりいけていそう
📝Example3
Input: arr = [10,20,30], fn = function constant() { return 42; }
Output: [42,42,42]
- i=0の時fn(10,0)、常に42を返す→result =[42]
- i=1の時fn(20,0)、常に42を返す→result =[42]
- i=1の時fn(20,0)、常に42を返す→result =[42]
これも問題なさそう
ということで提出してみます。
おぉ無事に通りました!むずすぎる〜〜〜