사실 반복문에서 쓰는 i는 index가 아니라 iteration
이다!
문제푸느라 자세히 읽지는 않았어서 지금 충격먹고 벨로그씀ㅋㅋㅋㅋ
iteration: 반복작업
iteratee: 반복되는 것
_.slice = function (arr, start, end) {
let _start = start || 0, //start가 undefined인 경우 0부터 동작
_end = end;
//입력받은 인덱스가 음수일 경우 뒤부터 매칭.
if( start < 0 ) _start = Math.max(0, arr.length + start);
if( end < 0 ) _end = Math.max(0, arr.length + end);
//end 생략되면 끝까지
//end값이 배열길이보다 길면 끝까지
if( _end === undefined || _end > arr.length ) _end = arr.length;
let result = [];
//start부터 end - 1 까지 +1하면서 반복한다.
for (let i = _start; i < _end; i++) {
//result에 arr[i] 차례대로 푸시한다.
result.push(arr[i]);
}
return result;
}
배열의 요소에서 처음부터 n개까지 담은 새로운 배열을 리턴한다.
_.take = function (arr, n) {
let result = []
// n이 undefined이거나 음수인 경우, 빈 배열 리턴.
if (n === undefined || n < 0) return result;
// n이 배열의 길이를 벗어날 경우, 전체 배열을 shallow copy한 새로운 배열을 리턴
else if (n > arr.length) return result = arr;
for (let i = 0; i < n; i++) {
result.push(arr[i]);
}
return result;
};
배열의 요소에서 처음부터 n개까지의 element를 제외하고 새로운 배열을 리턴한다.
//sudo code
//drop([1,2,3,4],2)
//n = 2, arr.length = 4
//arr[2], arr[3] 담아 리턴
_.drop = function (arr, n) {
let result = [];
// n이 undefined이거나 음수인 경우, 0인경우, 전체 배열을 shallow copy한 새로운 배열을 리턴
if (n === undefined || n <= 0) return result = arr;
// n이 배열의 길이를 벗어날 경우, 빈 배열 리턴
else if (n > arr.length) return result;
for (let i = n; i < arr.length; i++) {
result.push(arr[i]);
}
return result;
};
배열의 요소에서 뒤부터 n개의 elem을 담은 새로운 배열 리턴
_.last = function (arr, n) {
let result = [];
// n이 undefined이거나 음수인 경우, 배열의 마지막 요소만을 담은 배열을 리턴
if (n === undefined || n < 0) return result = [arr[arr.length - 1]];
// n이 배열의 길이를 벗어날 경우, 전체 배열을 shallow copy한 새로운 배열을 리턴
else if (n > arr.length) return result = arr;
// n이 0일때 빈배열 리턴
else if (n === 0) return result;
for (let i = n - 1; i < arr.length; i++) {
result.push(arr[i]);
}
return result;
};
iteretee익명함수를 활용한다 : (letter) => iterations.push(letter);
iteratee는 차례대로 데이터(element 또는 value), 접근자(index 또는 key), collection을 다룰 수 있어야한다.
iteratee(ele, idx, arr)
iteratee(val, key, obj) 순으로 인자 전달한다.
* const letters = ['a', 'b', 'c'];
* const iterations = [];
* _.each(letters, function(letter) {
* iterations.push(letter);
* });
* expect(iterations).to.eql(['a', 'b', 'c']);
//1. 배열 / 객체 분기를 나눈다.
_.each = function (collection, iteratee) {
if (Array.isArray(collection)) { //array인경우: iteratee(ele, idx, arr)
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection);
}
}
else { //object인경우: iteratee(val, key, obj)
for (let key in collection) { //객체일때 for in
iteratee(collection[key], key, collection);
}
}
};
arr의 요소와 같은 값이 전달되는 경우 배열에서의 위치를 리턴하고 아니면 -1 리턴
arr에 중복된 값이 확인된다면 가장 낮은 index를 리턴
_.indexOf = function (arr, target) {
// 배열의 모든 요소에 접근하려면, 순회 알고리즘(iteration algorithm)을 구현해야함.
let result = -1; //초기값으로 -1
_.each(arr, function (item, index) {
//arr = collection // iteratee = function()
if (item === target && result === -1) {
//collection[i] === target 확인
//result === -1 확인
//! result가 -1이 아니라면 가장 낮은 index값을 이미 찾은것
result = index;
//result에 i값을 준다.
}
});
return result;
};
_.filter는 test 함수를 통과하는 모든 요소를 담은 새로운 배열을 리턴합니다.
test 함수는 각 요소에 반복 적용됩니다.
_.filter = function (arr, test) {
let result = [];
_.each(arr, function (ele, idx, arr) {
//each(arr, iteratee)
if (test(ele)) { //test(element)의 결과(return 값)가 truthy일 경우
result.push(ele); //result에 push
}
})
return result;
};
reject는 filter와 정반대로 test 함수를 통과하지 않는 모든 요소를 담은 새로운 배열을 리턴
_.reject = function (arr, test) {
// TIP: 위에서 구현한 `filter` 함수를 사용해서 `reject` 함수를 구현해 보세요.
let result = [];
_.each(arr, function (ele) {
if (!test(ele)) { //falsy한 값이 나오면
result.push(ele); //result에 추가
}
})
return result;
};
TIP: 위에서 구현한
filter
함수를 사용해서reject
함수를 구현해 보세요._.reject = function (arr, test) { let result = []; _.filter(arr, function (item) { if (test(item) === false) { result.push(item); } }); return result; };
배열 요소가 중복되지 않도록 새로운 배열 리턴
_.uniq = function (arr) {
let result = []; //빈배열을 만들어준다.
_.each(arr, function (el) {
if (_.indexOf(result, el) === -1) { //result에 el 값이 없으면
result.push(el); //result에 push한다.
}
})
return result;
};
iteratee(반복되는 작업)를 배열의 각 요소에 적용(apply)한 결과를 담은 새로운 배열을 리턴
_.map = function (arr, iteratee) {
let result = [];
_.each(arr, function (ele) {
result.push(iteratee(ele));
})
return result;
};
객체 또는 배열을 요소로 갖는 배열과 각 요소에서 찾고자 하는 key 또는 index를 입력받아서
각 요소의 해당 값 또는 요소만을 추출해 새로운 배열에 저장하고
최종적으로 새로운 배열 리턴
//_.pluck을 _.each를 사용해 구현하면 아래와 같습니다.
let result = [];
_.each(arr, function (item) {
result.push(item[keyOrIdx]);
});
return result;
//_.map을 사용해 구현
let result = [];
_.map(arr, function (el) {
result.push(el[keyOrIdx])
})
return result;
배열을 순회해 각 요소에 iteratee 함수 적용하고
그 결과값 계속해서 누적(acc)
최종적으로 누적된 결과값 리턴
reduce는 배열이라는 다수의 정보가 하나의 값으로 축소된다.
_.reduce = function (arr, iteratee, initVal) {
let acc = initVal;
_.each(arr, function (cur, idx, val) {
if (initVal === undefined && idx === 0) { //초기값이 없는경우
acc = cur; //누적값에 현재값을 준다
} else { //초기값이 주어진경우
acc = iteratee(acc, cur, idx, val);
}
})
return acc;
};