엔진 뚜껑을 어떻게 비추고, 줄이고, 여과합니까
지도.
Map은 함수(iteratee) 매핑 목록의 각 값을 변환하여 새 값 배열을 생성합니다.
iteratee
에 세 가지 매개 변수를 전달한다. value
, 그 다음에 교체된 index
(또는 key
), 마지막으로 전체 list
에 대한 인용이다.map([1, 2, 3], function(num){ return num * 3; });
// => [3, 6, 9]
map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
// => [3, 6, 9]
iteratee 매핑 집합의 모든 값을 통해 새로운 값 그룹을 되돌려줍니다.iteratee를 호출할 때마다 세 개의 매개 변수를 사용하여 호출합니다: (요소, 인덱스 | 키, 집합)
하나가 전달되면 상하문에 귀속됩니다.
퀴즈:
map = function (collection, iteratee, context) {
var result = [];
if (Object.prototype.toString.call(collection) == '[object Object]') {
for (var key in collection) {
if (collection.hasOwnProperty(key)) {
result.push(iteratee.call(context, collection[key], key, collection));
}
}
} else {
for (var i = 0; i < collection.length; i++) {
result.push(iteratee.call(context, collection[i], i, collection));
}
}
return result;
};
map 방법은 수조의 모든 요소에 함수를 적용하여 수조를 변환하고 되돌아오는 값에 따라 새 수조를 구축합니다.새 그룹의 길이는 collection
과 같지만, 원소는 리셋 함수 iteratee
에서 새 값으로 비추게 됩니다.collection
, iteratee
과 context
에서 세 가지 파라미터를 전달한다.처음에 우리는 어떻게 집합을 교체해야 하는지를 결정했다. 만약에 집합(우리가 비치는 대상)이 object Object
이라면 우리는 for in
문법을 사용하고 그 어떠한 상황에서도 표준 for
순환을 사용한다.순환 중, 우리는 모든 원소에 대해
iteratee
방법을 사용하여 call
함수 (리셋) 를 호출한 결과를 result
수조로 전송할 것이다.result
은 iteratee
에서 변환된 요소로 구성된 수조이다.우리는
call
을 사용하여 전달된 파라미터를 추적하는데 그 중에서 상하문(this
)과 현재 원소 collection[i]
, 인덱스 i
, 그리고 collection
의 나머지 원소를 명확하게 정의했다.줄다
Reduce는 inject와 foldl이라고도 하는데 Reduce는 하나의 값 목록을 하나의 값으로 귀결시킨다.
var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
// => 6
Reduce는 값 세트를 하나의 값으로 분해합니다.누적기는 복원의 초기 상태이며, 그 다음 단계는 반드시 누적기에서 되돌아와야 한다.퀴즈:
each = function (collection, iteratee, context) {
if (Object.prototype.toString.call(collection) == '[object Object]') {
for (var key in collection) {
if (collection.hasOwnProperty(key)) {
iteratee.call(context, collection[key], key, collection);
}
}
} else {
for (var i = 0; i < collection.length; i++) {
iteratee.call(context, collection[i], i, collection);
}
}
return collection;
};
reduce = function (collection, iteratee, accumulator, context) {
each(collection, function (element, key) {
if (accumulator !== undefined) {
accumulator = iteratee.call(context, accumulator, element, key, collection);
} else {
accumulator = element;
}
});
return accumulator;
};
Each
방법은 리셋 함수를 사용하여 원소 집합에서 순환한다. 모든 방법과 맵 간의 관건적인 차이점은 모든 방법이 새로운 수조로 돌아가지 않고 원시 집합을 수정하지 않는다는 것이다.Each
을 사용할 때, 리셋을 통해 새 집합을 변환해야 할 경우, 결과를 새 변수에 저장하는 것이 좋습니다.내가
Each
을 사용한 이유는 우리가 원시 대상을 수정하지 않은 상황에서 iteratee
을 사용하여 모든 요소를 바꾸기를 원하기 때문이다. 이렇게 하면 Reduce가 즐겁게 자신에게 돌아갈 수 있기 때문이다.Reduce를 생각하는 간단한 방법은 한 번에 하나의 수조를 하나의 원소로 접고 그 중의 모든 원소를 하나의 단일한 기본값으로 조합하는 것을 상상하는 것이다.
Reduce는 Map 및 Filter 메서드에 비해
accumulator
의 추가 매개 변수를 사용합니다.accumlator
은 Reduce 방법에서 되돌아오는 총액이나 초기값으로 사용됩니다.우리는 each를 사용하여 collection
의 모든 원소 (왼쪽에서 오른쪽으로) 를 교체하는데, 이 원소는 하나의 값으로 간소화된다.accumulator
은 초기값 또는 집합의 첫 번째 요소로 설정됩니다.Reduce를 사용하거나 문제가 발생할 경우 일반적으로 초기 값을 중심으로 권장 사항을 읽은 적이 있습니다.이것은 Reduce가 그룹의 첫 번째 항목이 초기 값이라고 가정하기 때문에, 되돌려주고 싶은 총액이나 최종 값에 따라 문제가 발생할 수 있습니다.문제가 발생하면 항상 되돌아와 초기 값을 확인하십시오.
더 강력한 Reduce 구현으로 더 많은 에지 처리 가능:
function reduce(array, callback, initialValue) {
var startingIndex = 0;
var resultSoFar = initialValue;
var length = array.length;
var arrayIndexes = Object.keys(array);
if (arguments.length < 3) {
// Array is empty, throw typeError
if (arrayIndexes.length === 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
// If array has one element, just return it
if (arrayIndexes.length === 1) {
var onlyIndex = arrayIndexes[0];
var onlyElement = array[onlyIndex];
return onlyElement;
}
// We want to skip holes at the beginning of the array
while (startingIndex in array === false && startingIndex < length) {
startingIndex++;
}
resultSoFar = array[startingIndex];
startingIndex++
// has initial value
} else {
// check if array is empty
if (arrayIndexes.length === 0) {
return initialValue;
}
}
for (var i = startingIndex; i < length; i++) {
if (i in array) {
resultSoFar = callback(resultSoFar, array[i], i, array);
}
}
return resultSoFar;
};
필터
필터는 목록의 모든 값을 검사하고 실제 값 테스트를 통과한 모든 값의 그룹을 되돌려줍니다.
Filter는 실제 값 테스트를 통과한 값만 포함하는 새로운 그룹을 제공합니다.
var evens = filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
// => [2, 4, 6]
집합의 모든 값을 보고 실제 값 테스트를 통과한 모든 값의 수조(predicate
)를 되돌려줍니다.술어는 세 개의 매개 변수로 호출됩니다: (원소, 인덱스 | 키, 집합). 매개 변수를 전달하면 상하문에 귀속됩니다.퀴즈:
컨텍스트가 전달된 경우
filter = function (collection, predicate, context) {
var result = [];
if (Object.prototype.toString.call(collection) == '[object Object]') {
for (var key in collection) {
if (collection.hasOwnProperty(key)) {
if (predicate.call(context, collection[key], key, collection)) {
result.push(collection[key]);
}
}
}
} else {
for (var i = 0; i < collection.length; i++) {
if (predicate.call(context, collection[i], i, collection)) {
result.push(collection[i]);
}
}
}
return result;
};
필터가 원시 그룹 서브집합을 포함하는 새 그룹을 만듭니다.결과는 테스트를 통과한 원소(predicate
)를 포함하고 이 원소는 제공된 함수로 이루어지며 이 함수는true나false로 되돌아와야 한다.실현 과정에서
collection
, predicate
과 context
에서 세 가지 파라미터를 전달했다.우리는 어떻게 반복해서 집합해야 하는지를 확정했다. 순환 중에 우리는 집합에서 모든 원소를 얻고 이 원소를 전달한다. 만약 그것이 predicate
방법으로 call
함수 (리셋) 를 호출하는 조건에 부합된다면,true로 돌아가는 모든 원소는 결과 그룹으로 전송될 것이다.예를 들면 다음과 같습니다.
다음은 맵, Filter, Reduce를 사용하는 일련의 예를 열거했고, 마지막으로 더 높은 예가 하나 더 있습니다.
한 조의 숫자에서 화합을 구하다
const euros = [13.45, 289.30, 89.4, 142.67];
const sum = euros.reduce((total, amount) => total += amount);
console.log(sum);
// => 534.82
발생 횟수를 세다
const phones = ['iphone x', 'pixel 2', 'samsung s8', 'pixel 2', 'iphone 7', 'pixel 2', 'samsung s8', 'iphone x', 'huwei mate'];
const count = phones.reduce((count, phone) => {
count[phone] = (count[phone] || 0) + 1 ;
return count;
} , {})
console.log(count)
// { 'iphone x': 2, 'pixel 2': 3, 'samsung s8': 2, 'iphone 7': 1, 'huwei mate': 1 }
다차원 배열 펴기
const multiArray = [[2, 4, 6, 8], [10, 12, 14, 16], [18, 20, 22, 24]];
let flattened = multiArray.reduce((arr, arrSub) => {
return arr.concat(arrSub);
}, []);
console.log(flattened);
// => [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24 ]
객체 등록 정보를 배열로 플랫화합니다.
const phones = [
{model: 'Iphone', manufacturer: 'Apple', tags: ['face ID','animated emojis']},
{model: 'Pixel', manufacturer: 'Google', tags: ['Google assistant','Touch ID','Best camera']},
{model: 'S8', manufacturer: 'Samsung', tags: ['Curved screen','Best display']}
];
// Use reduce to get all colors into a single array
var tagsArr = phones.reduce((phones, phone) => {
return phones.concat(phone.tags);
}, []);
console.log(tagsArr);
// [ 'face ID', 'animated emojis', 'Google assistant', 'Touch ID', 'Best camera', 'Curved screen', 'Best display' ]
맵, 축소 및 필터를 연결하려면 다음과 같이 하십시오.
var totals = [
{ amount: 3 },
{ amount: 6 },
{ amount: 8 },
{ amount: 22 },
{ amount: 15 },
]
// Filter amounts above 6 and calculate the total using reduce
var largestAmount = totals
.filter((order) => order.amount > 6)
.map((order) => order.amount)
.reduce((total, amount) => {
return total + amount;
},0);
console.log(largestAmount);
// => 45
링크의 또 다른 예.var animals = [
{ name: 'Hubert', type: 'panther', age: 3 },
{ name: 'George', type: 'lion', age: 4 },
{ name: 'Fredrick', type: 'lion', age: 6 },
{ name: 'Midnight', type: 'panther', age: 9 },
];
var panthers = animals
.filter((animal) => animal.type === 'panther')
.map((panther) => panther.name);
console.log(panthers);
// => [ 'Hubert', 'Midnight' ]
var totalLionYears = animals
.filter((x) => x.type === 'lion')
.map((x) => x.age)
.reduce((prev, cur) => {
return prev + cur
}, 0);
console.log(totalLionYears);
// => 10
하나 더 있어요.var activityData = [
{activity: 'Running', distance: '4', time: '120'},
{activity: 'Cycling', distance: '12', time: '340'},
{activity: 'Swimming', distance: '38', time: '510'},
];
const totalDistance = activityData
.map((activity) => Number(activity.distance))
.reduce((total, distance) => {
return total + distance;
}, 0);
console.log(totalDistance);
// => 54
const totalTime = activityData
.map((activity) => Number(activity.time))
.reduce((total, time) => {
return total + time;
}, 0);
const formatTime = num => {
let hours = Math.floor(num / 60);
let minutes = num % 60;
return hours + ':' + minutes;
}
console.log(formatTime(totalTime));
// => 16:10
const enduringActivity = activityData
.filter((activity) => activity.time > 300)
.map((name) => name.activity);
console.log('The most enduring activities are: ' + enduringActivity);
// => The most enduring activities are: Cycling, Swimming
구조화되지 않은 데이터를 대상으로 축소
txt 파일이나 그룹의 데이터를 처리하는 데 사용합니다.
// #4 Reduce an array of unstructured data into a structured object
var orderData = [
['cameron jenkinson', 'macha tea', '4', '2'],
['cameron jenkinson', 'javascript book', '16', '1'],
['lois male', 'glitter sticks', '4', '4'],
['lois male', 'gold paint', '12', '2']
];
const output = orderData.reduce((customers, [name, order, price, quantity]) => {
customers[name] = customers[name] || [];
customers[name].push({
order,
price,
quantity
});
return customers;
}, {});
console.log(JSON.stringify(output, null, 2));
/*
"cameron jenkinson": [
{
"order": "macha tea",
"price": "4",
"quantity": "2"
},
{
"order": "javascript book",
"price": "16",
"quantity": "1"
}
],
"lois male": [
{
"order": "glitter sticks",
"price": "4",
"quantity": "4"
},
{
"order": "gold paint",
"price": "12",
"quantity": "2"
}
]
}
*/
고급 샘플
이러한 방법은 데이터를 더 쉽게 소모하는 문제에 부딪히면 API 데이터를 원하는 형식으로 변환할 수 있습니다.
아래의 예에서 우리는
timesObject
이 있는데 이것은 매일의 개방 시간 구조를 대표한다.Reduce와 Map을 사용하여 이 대상을iterable 그룹으로 변환하려고 합니다.
const timesObject = {
monday: [{ open: '00:00', close: '23:00' }],
tuesday: [{ open: '00:00', close: '23:00' }],
wednesday: [{ open: '01:00', close: '23:00' }],
thursday: [],
friday: [],
saturday: [],
sunday: [],
};
function objectIntoArray(timesObject) {
if (!timesObject || Object.keys(timesObject).length === 0) return [];
let res = Object.keys(timesObject)
// filter the days which have opening times
.filter(day => timesObject[day].length)
.reduce((allDays, day) => {
let time = timesObject[day][0];
let openingTime = time.open + '-' + time.close;
allDays[openingTime] = allDays[openingTime] || { open: time.open, close: time.close, days: [] };
// push the days that correspond with the same opening time
allDays[openingTime].days.push(day);
return allDays;
}, {});
// map over each openining time into a new array
let array = Object.keys(res).map(key => res[key])
return array;
}
objectIntoArray(timesObject);
/*
[ { open: '00:00', close: '23:00', days: [ 'monday', 'tuesday' ] },
{ open: '01:00', close: '23:00', days: [ 'wednesday' ] } ]
*/
이 모든 것은 지도, 감소와 여과를 위한 것이다.나는 이것이 너에게 도움이 되기를 바란다.
Reference
이 문제에 관하여(엔진 뚜껑을 어떻게 비추고, 줄이고, 여과합니까), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/cjjenkinson/how-map-reduce-and-filter-work-under-the-hood-128n텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)