// Underscore.js 1.3.3
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore는 MIT 라이센스에 따라 무료로 배포 가능합니다.
// Underscore의 일부는 Prototype에서 영감을 받거나 차용되었습니다.
// Oliver Steele의 Functional 및 John Resig의 Micro-Templating.
// 모든 세부 사항 및 문서는 다음을 참조하세요.
// http://documentcloud.github.com/underscore
(기능() {
// 브라우저에서는 창 객체로 표시되고 Node.js에서는 전역 객체로 표시되는 전역 객체를 생성합니다.
var 루트 = 이것;
//"_"(밑줄 변수)를 덮어쓰기 전의 값을 저장합니다.
// 이름 충돌이 있거나 사양을 고려하는 경우 _.noConstrict() 메서드를 사용하여 Underscore가 차지하기 전의 "_" 값을 복원하고 이름 변경을 위해 Underscore 개체를 반환할 수 있습니다.
var 이전Underscore = 루트._;
//내부 공유 및 사용을 위해 빈 객체 상수를 생성합니다.
var 차단기 = {};
//빠른 호출을 용이하게 하기 위해 내장 객체의 프로토타입 체인을 로컬 변수에 캐시합니다.
var ArrayProto = Array.prototype, //
ObjProto = Object.prototype, //
FuncProto = 함수.프로토타입;
//빠른 호출을 위해 지역 변수에 내장된 객체 프로토타입의 공통 메서드를 캐시합니다.
var 슬라이스 = ArrayProto.slice, //
unshift = ArrayProto.unshift, //
toString = ObjProto.toString, //
hasOwnProperty = ObjProto.hasOwnProperty;
// 이는 JavaScript 1.6에서 제공되는 몇 가지 새로운 메소드를 정의합니다.
// 호스트 환경이 이러한 메소드를 지원하는 경우 먼저 호출됩니다. 호스트 환경에서 이를 제공하지 않는 경우 Underscore에 의해 구현됩니다.
var NativeForEach = ArrayProto.forEach, //
NativeMap = ArrayProto.map, //
NativeReduce = ArrayProto.reduce, //
NativeReduceRight = ArrayProto.reduceRight, //
NativeFilter = ArrayProto.filter, //
NativeEvery = ArrayProto.every, //
NativeSome = ArrayProto.some, //
NativeIndexOf = ArrayProto.indexOf, //
NativeLastIndexOf = ArrayProto.lastIndexOf, //
NativeIsArray = Array.isArray, //
NativeKeys = Object.keys, //
NativeBind = FuncProto.bind;
// Underscore 래퍼를 반환하는 개체 스타일 호출 메서드를 만듭니다. 래퍼 개체의 프로토타입에는 Underscore의 모든 메서드가 포함되어 있습니다(DOM 개체를 jQuery 개체로 래핑하는 것과 유사).
var _ = 함수(obj) {
// 모든 Underscore 객체는 래퍼 객체를 통해 내부적으로 생성됩니다.
새로운 래퍼(obj)를 반환합니다.
};
// 다른 호스트 환경의 경우 Undersocre의 명명된 변수를 다른 개체에 저장합니다.
if( typeof imports !== 'undefine') {// Node.js 환경
if( 모듈 유형 !== '정의되지 않음' && module.exports) {
내보내기 = module.exports = _;
}
수출._ = _;
} else {//브라우저 환경에서 Underscore라는 이름의 변수가 window 객체에 걸려 있습니다.
루트['_'] = _;
}
// 버전 설명
_.VERSION = '1.3.3';
// 컬렉션 관련 메서드(데이터 및 객체에 대한 일반적인 처리 방법)
//-------
// 프로세서를 반복하고 컬렉션의 각 요소에 대해 프로세서 메서드를 실행합니다.
var 각각 = _.each = _.forEach = function(obj, iterator, context) {
//null 값을 처리하지 않음
if(obj == null)
반품;
if(nativeForEach && obj.forEach === NativeForEach) {
// 호스트 환경에서 지원하는 경우 JavaScript 1.6에서 제공하는 forEach 메서드가 먼저 호출됩니다.
obj.forEach(반복자, 컨텍스트);
} else if(obj.length === obj.length) {
//<array>의 각 요소에 대해 프로세서 메서드를 실행합니다.
for(var i = 0, l = obj.length; i < l; i ) {
if( i in obj && iterator.call(context, obj[i], i, obj) === 차단기)
반품;
}
} 또 다른 {
// <object>의 각 요소에 대해 프로세서 메서드를 실행합니다.
for(obj의 var 키) {
if(_.has(obj, key)) {
if(iterator.call(context, obj[key], key, obj) === 차단기)
반품;
}
}
}
};
// 반복 프로세서, 각 메소드와의 차이점은 맵이 각 반복의 반환 값을 저장하고 새 배열로 반환한다는 것입니다.
_.map = _.collect = function(obj, iterator, context) {
//반환값을 저장하는 데 사용되는 배열
var 결과 = [];
if(obj == null)
결과를 반환합니다.
// 호스트 환경에서 제공하는 맵 메소드 호출 우선순위를 지정합니다.
if(nativeMap && obj.map === 기본 맵)
return obj.map(반복자, 컨텍스트);
// 컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
// 각 반복의 반환 값을 결과 배열에 저장합니다.
results[results.length] = iterator.call(컨텍스트, 값, 인덱스, 목록);
});
//처리 결과를 반환합니다.
if(obj.길이 === obj.길이)
결과.길이 = obj.길이;
결과를 반환합니다.
};
// 컬렉션의 각 요소를 반복 프로세서에 넣고 이 반복의 반환 값을 "메모"로 다음 반복에 전달합니다. 일반적으로 결과를 누적하거나 데이터를 연결하는 데 사용됩니다.
_.reduce = _.foldl = _.inject = function(obj, iterator, 메모, 컨텍스트) {
// 매개변수 개수만큼 초기값이 있는지 확인
var 초기 = 인수.길이 >
if(obj == null)
obj = [];
// 호스트 환경에서 제공하는 축소 메소드 호출 우선순위를 지정합니다.
if(nativeReduce && obj.reduce === NativeReduce && false) {
if(컨텍스트)
iterator = _.bind(반복자, 컨텍스트);
초기 반환 ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
// 컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
if(!initial) {
// 초기값이 없으면 첫 번째 요소가 초기값으로 사용되며, 객체 컬렉션이 처리되면 기본값은 첫 번째 속성의 값입니다.
메모 = 값;
초기 = 사실;
} 또 다른 {
// 처리 결과를 기록하고 결과를 다음 반복으로 전달합니다.
memo = iterator.call(컨텍스트, 메모, 값, 인덱스, 목록);
}
});
if(!초기)
throw new TypeError('초기값이 없는 빈 배열 감소');
메모 반환;
};
// 감소와 유사하게 컬렉션의 요소를 반대 방향으로 반복합니다(즉, 마지막 요소에서 시작하여 첫 번째 요소까지).
_.reduceRight = _.foldr = function(obj, iterator, 메모, 컨텍스트) {
var 초기 = 인수.길이 >
if(obj == null)
obj = [];
// 호스트 환경에서 제공하는 ReduceRight 메소드 호출 우선순위를 지정합니다.
if(nativeReduceRight && obj.reduceRight === NativeReduceRight) {
if(컨텍스트)
iterator = _.bind(반복자, 컨텍스트);
초기 반환 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
//컬렉션의 요소 순서를 반대로 바꿉니다.
var reversed = _.toArray(obj).reverse();
if(컨텍스트 && !초기)
iterator = _.bind(반복자, 컨텍스트);
//리듀스 메소드를 통해 데이터 처리
return 초기 ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
};
// 컬렉션의 요소를 순회하고 프로세서 확인을 통과할 수 있는 첫 번째 요소를 반환합니다.
_.find = _.Detect = function(obj, iterator, context) {
// 결과는 검증을 통과할 수 있는 첫 번째 요소를 저장합니다.
var 결과;
// any 메소드를 통해 데이터를 탐색하고 검증을 통과한 요소를 기록합니다.
// (iteration 중 프로세서 반환 상태를 확인하는 경우 여기서는 각각의 메소드를 사용하는 것이 더 적절할 것입니다)
모든(obj, 함수(값, 인덱스, 목록)) {
// 프로세서가 반환한 결과를 Boolean 타입으로 변환하여 값이 true이면 현재 요소를 기록하여 반환한다.
if(iterator.call(context, value, index, list)) {
결과 = 값;
사실을 반환;
}
});
결과 반환;
};
// find 메소드와 비슷하지만 filter 메소드는 컬렉션의 확인된 모든 요소를 기록합니다.
_.filter = _.select = function(obj, iterator, context) {
// 유효성 검사를 통과한 요소의 배열을 저장하는 데 사용됩니다.
var 결과 = [];
if(obj == null)
결과를 반환합니다.
// 호스트 환경에서 제공하는 필터 메소드를 우선적으로 호출합니다.
if(nativeFilter && obj.filter === NativeFilter)
return obj.filter(반복자, 컨텍스트);
// 컬렉션의 요소를 반복하고 프로세서에서 확인한 요소를 배열에 넣고 반환합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
if(iterator.call(컨텍스트, 값, 인덱스, 목록))
결과[결과.길이] = 값;
});
결과를 반환합니다.
};
// 필터 메소드의 반대 효과, 즉 프로세서 검증을 통과하지 못한 요소 목록을 반환합니다.
_.reject = function(obj, iterator, context) {
var 결과 = [];
if(obj == null)
결과를 반환합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
if(!iterator.call(컨텍스트, 값, 인덱스, 목록))
결과[결과.길이] = 값;
});
결과를 반환합니다.
};
//컬렉션의 모든 요소가 프로세서 확인을 통과할 수 있으면 true를 반환합니다.
_.every = _.all = function(obj, iterator, context) {
var 결과 = true;
if(obj == null)
결과 반환;
// 호스트 환경에서 제공하는 모든 메소드를 우선적으로 호출합니다.
if(nativeEvery && obj.every === NativeEvery)
return obj.every(반복자, 컨텍스트);
//컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
// 이는 result = (result && iterator.call(context, value, index, list))로 이해됩니다.
// 프로세서의 결과가 Boolean 타입으로 변환된 후 참값인지 확인
if(!( 결과 = 결과 && iterator.call(컨텍스트, 값, 인덱스, 목록)))
복귀 차단기;
});
반환 !!결과;
};
// 컬렉션의 요소가 부울 유형으로 변환될 때 참값을 갖는지 확인합니까? 아니면 프로세서에서 처리된 후에 참값을 갖는지 확인합니까?
var any = _.some = _.any = function(obj, iterator, context) {
// 프로세서 매개변수가 지정되지 않은 경우 기본 프로세서 함수는 요소 자체를 반환하고 반복 중에 요소를 부울 유형으로 변환하여 참값인지 확인합니다.
반복자 || ( 반복자 = _.identity);
var 결과 = 거짓;
if(obj == null)
결과 반환;
// 호스트 환경에서 제공하는 일부 메소드 호출에 우선순위를 부여합니다.
if(nativeSome && obj.some === NativeSome)
return obj.some(반복자, 컨텍스트);
//컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
if(결과 || ( 결과 = iterator.call(컨텍스트, 값, 인덱스, 목록)))
복귀 차단기;
});
반환 !!결과;
};
// 컬렉션에 대상 매개변수와 정확히 일치하는 값이 있는지 확인합니다. (데이터 유형도 일치합니다.)
_.include = _.contains = function(obj, 대상) {
var 발견 = false;
if(obj == null)
반품을 찾았습니다.
// 호스트 환경에서 제공하는 Array.prototype.indexOf 메서드 호출 우선순위를 지정합니다.
if(nativeIndexOf && obj.indexOf === NativeIndexOf)
return obj.indexOf(target) != -1;
// any 메소드를 통해 컬렉션의 요소를 반복하고 요소의 값과 유형이 대상과 완전히 일치하는지 확인합니다.
발견 = 모든(obj, 함수(값)) {
반환 값 === 대상;
});
반품을 찾았습니다.
};
// 요소의 호출 메서드에 전달될 세 번째 매개변수부터 시작하여 컬렉션에 있는 모든 요소의 동일한 이름의 메서드를 순서대로 호출합니다.
// 모든 메소드의 처리 결과를 저장하는 배열을 반환
_.invoke = 함수(obj, 메서드) {
// 같은 이름의 메소드 호출 시 전달되는 매개변수 (3번째 매개변수부터 시작)
var args = Slice.call(인수, 2);
// 각 요소의 메소드를 차례로 호출하고 그 결과를 배열에 담아 반환한다.
return _.map(obj, function(value) {
return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
});
};
// 객체 목록으로 구성된 배열을 탐색하고 각 객체의 지정된 속성에 대한 값 목록을 반환합니다.
_.pluck = function(obj, 키) {
// 객체에 속성이 존재하지 않는 경우, 정의되지 않음을 반환합니다.
return _.map(obj, function(value) {
반환값[키];
});
};
//컬렉션의 최대값을 반환하고, 비교할 수 있는 값이 없으면 정의되지 않은 값을 반환합니다.
_.max = 함수(obj, 반복자, 컨텍스트) {
// 컬렉션이 배열이고 프로세서가 사용되지 않는 경우 Math.max를 사용하여 최대값을 얻습니다.
// 일반적으로 일련의 숫자형 데이터가 배열로 저장됩니다.
if(!iterator && _.isArray(obj) && obj[0] === obj[0])
return Math.max.apply(Math, obj);
// null 값의 경우 음의 무한대를 직접 반환합니다.
if(!iterator && _.isEmpty(obj))
반환 -무한대;
// 임시 개체, 계산은 비교 프로세스 중 최대값을 저장하는 데 사용됩니다(임시).
변수 결과 = {
계산 : -무한대
};
//컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
// 프로세서 매개변수가 지정된 경우 비교 데이터는 프로세서가 반환한 값이고, 그렇지 않으면 각 순회 중 기본값이 직접 사용됩니다.
var 계산 = 반복자 ? iterator.call(컨텍스트, 값, 인덱스, 목록) : 값;
// 비교 값이 이전 값보다 크면 현재 값을 result.value에 넣습니다.
계산됨 >= 결과.계산됨 && ( 결과 = {
가치: 가치,
계산하다 : 계산하다
});
});
// 최대값을 반환합니다.
결과.값을 반환합니다.
};
//세트의 최소값을 반환합니다. 처리 프로세스는 max 메소드와 일치합니다.
_.min = 함수(obj, 반복자, 컨텍스트) {
if(!iterator && _.isArray(obj) && obj[0] === obj[0])
return Math.min.apply(Math, obj);
if(!iterator && _.isEmpty(obj))
무한대를 반환합니다.
변수 결과 = {
계산됨: 무한대
};
각각(obj, 함수(값, 인덱스, 목록)) {
var 계산 = 반복자 ? iterator.call(컨텍스트, 값, 인덱스, 목록) : 값;
계산된 < 결과.계산된 && ( 결과 = {
가치: 가치,
계산하다 : 계산하다
});
});
결과.값을 반환합니다.
};
// 배열을 정렬할 필요가 없도록 난수를 사용합니다.
_.shuffle = 함수(obj) {
// 섞인 변수는 처리 과정과 최종 결과 데이터를 저장합니다.
var shuffled = [], rand;
//컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스, 목록)) {
// 난수를 생성합니다. 난수는 <0-현재 처리된 숫자>
rand = Math.floor(Math.random() * (색인 1));
// 섞인 배열의 끝에 무작위로 얻은 요소를 넣습니다.
섞인[인덱스] = 섞인[랜드];
//이전에 얻은 난수 위치에 가장 최근의 값을 삽입
shuffled[rand] = 값;
});
// 무작위로 섞인 컬렉션 요소를 저장하는 배열을 반환합니다.
섞여서 돌아옴;
};
// 특정 필드나 값에 따라 컬렉션의 요소를 정렬합니다.
// Array.prototype.sort 메소드와 비교하여 sortBy 메소드는 객체 정렬을 지원합니다.
_.sortBy = function(obj, val, context) {
// val은 객체의 속성이거나 프로세서 함수여야 합니다. 프로세서인 경우 비교해야 하는 데이터를 반환해야 합니다.
var iterator = _.isFunction(val) ? val : function(obj) {
반환 객체[발];
};
// 호출 순서: _.pluck(_.map().sort());
// _.map() 메서드를 호출하여 컬렉션을 순회하고 컬렉션의 요소를 값 노드에 넣고 요소에서 비교해야 하는 데이터를 기준 속성에 넣습니다.
//criteria 속성의 데이터에 따라 컬렉션의 요소를 정렬하려면 sort() 메서드를 호출합니다.
// pluck을 호출하여 정렬된 객체 컬렉션을 얻고 반환합니다.
return _.pluck(_.map(obj, function(value, index, list)) {
반품 {
가치: 가치,
기준: iterator.call(컨텍스트, 값, 인덱스, 목록)
};
}).sort(함수(왼쪽, 오른쪽) {
var a = 왼쪽.기준, b = 오른쪽.기준;
만약(a ===
무효 0)
1을 반환합니다.
만약(b ===
무효 0)
-1을 반환합니다.
a <b ? -1:a >b ?
}), '값');
};
// 프로세서가 반환한 키에 따라 컬렉션의 요소를 여러 배열로 나눕니다.
_.groupBy = 함수(obj, val) {
var 결과 = {};
// val은 그룹화를 위해 프로세서 함수로 변환됩니다. val이 Function 유형 데이터가 아닌 경우 요소 필터링 시 키 값으로 사용됩니다.
var iterator = _.isFunction(val) ? val : function(obj) {
반환 객체[발];
};
//컬렉션의 요소를 반복합니다.
각각(obj, 함수(값, 인덱스)) {
// 프로세서의 반환 값을 키로 사용하고 동일한 키 요소를 새 배열에 넣습니다.
var key = iterator(값, 인덱스);
(결과[키] || (결과[키] = [])).push(값);
});
// 그룹화된 데이터를 반환합니다.
결과 반환;
};
_.sortedIndex = function(array, obj, iterator) {
반복자 || ( 반복자 = _.identity);
var low = 0, high = array.length;
while(낮음 < 높음) {
var mid = (낮음 높음) >> 1;
iterator(array[mid]) < iterator(obj) ? low = mid 1 : high = mid;
}
낮게 반환;
};
//컬렉션을 배열로 변환하고 반환
// 일반적으로 인수를 배열로 변환하거나, 정렬되지 않은 객체 컬렉션을 데이터 형태의 정렬된 컬렉션으로 변환하는 데 사용됩니다.
_.toArray = 함수(obj) {
만약(!obj)
반품 [];
if(_.isArray(obj))
return Slice.call(obj);
//인수를 배열로 변환
if(_.isArguments(obj))
return Slice.call(obj);
if(obj.toArray && _.isFunction(obj.toArray))
return obj.toArray();
//객체를 객체의 모든 속성(객체 프로토타입 체인의 속성 제외)의 값 목록이 포함된 배열로 변환합니다.
_.values(obj)를 반환합니다.
};
// 컬렉션의 요소 수를 계산합니다.
_.size = 함수(obj) {
// 컬렉션이 배열이면 배열 요소의 개수를 셉니다.
// 컬렉션이 객체인 경우 객체의 속성 수를 계산합니다(객체의 프로토타입 체인에 있는 속성 제외).
_.isArray(obj) ? obj.length : _.keys(obj).length;
};
// 배열 관련 메소드
// ---------------
// 지정된 배열의 첫 번째 또는 n 요소를 순서대로 반환합니다.
_.first = _.head = _.take = function(array, n, Guard) {
// 매개변수 n이 지정되지 않은 경우 첫 번째 요소를 반환합니다.
// n이 지정되면 지정된 수의 n 요소를 순서대로 포함하는 새 배열을 반환합니다.
//guard 매개변수는 첫 번째 요소만 반환되는지 확인하는 데 사용됩니다. Guard가 true인 경우 지정된 숫자 n은 유효하지 않습니다.
return (n != null) && !guard ? Slice.call(array, 0, n) : array[0];
};
//첫 번째 요소를 제외한 다른 요소를 포함하거나 마지막 요소부터 앞으로 지정된 n 요소를 제외하는 새 배열을 반환합니다.
// 첫 번째 방법과의 차이점은 배열 이전에 필요한 요소의 위치를 먼저 결정하고, 초기화는 배열 끝에서 제외된 요소의 위치를 결정한다는 점입니다.
_.initial = 함수(배열, n, 가드) {
// 매개변수 n이 전달되지 않으면 마지막 요소를 제외한 다른 요소가 기본적으로 반환됩니다.
// 매개변수 n이 전달되면 마지막 요소부터 n개 요소를 제외한 다른 요소가 반환됩니다.
// Guard는 하나의 요소만 반환되도록 하는 데 사용됩니다. Guard가 true인 경우 지정된 숫자 n은 유효하지 않습니다.
return Slice.call(array, 0, array.length - ((n == null) || Guard ? 1 : n));
};
//배열의 마지막 n개 요소 또는 지정된 n개 요소를 역순으로 반환합니다.
_.last = 함수(배열, n, 가드) {
if((n != null) && !guard) {
// 구한 요소 위치 n을 배열 끝까지 계산하여 지정하고, 새로운 배열로 반환
return Slice.call(array, Math.max(array.length - n, 0));
} 또 다른 {
// 숫자가 지정되지 않거나 Guard가 true인 경우 마지막 요소만 반환됩니다.
반환 배열[array.length - 1];
}
};
// 첫 번째 또는 지정된 처음 n개 요소를 제외한 다른 요소를 가져옵니다.
_.rest = _.tail = function(배열, 인덱스, 가드) {
// 배열의 끝까지 슬라이스의 두 번째 위치 매개변수를 계산합니다.
// 인덱스가 지정되지 않거나 가드 값이 true인 경우 첫 번째 요소를 제외한 다른 요소를 반환합니다.
// (index == null) 값이 true일 경우, 슬라이스 함수에 전달된 매개변수는 자동으로 1로 변환됩니다.
return Slice.call(array, (index == null) || Guard ? 1 : index);
};
// 값이 true로 변환될 수 있는 배열의 모든 요소를 반환하고 새 배열을 반환합니다.
// 변환할 수 없는 값에는 false, 0, '', null, undefine, NaN 등이 있으며, 이러한 값은 false로 변환됩니다.
_.compact = 함수(배열) {
return _.filter(배열, 함수(값) {
반환!!값;
});
};
// 다차원 숫자를 1차원 배열로 결합하여 심층 병합을 지원합니다.
//shallow 매개변수는 병합 깊이를 제어하는 데 사용됩니다.shallow가 true인 경우 첫 번째 레이어만 병합되며 기본적으로 깊은 병합이 수행됩니다.
_.Flatten = 함수(배열, 얕은) {
// 배열의 각 요소를 반복하고 반환 값을 데모로 다음 반복에 전달합니다.
return _.reduce(array, function(memo, value) {
// 요소가 여전히 배열인 경우 다음과 같이 판단합니다.
// - Deep Merge가 수행되지 않는 경우 Array.prototype.concat을 사용하여 현재 배열과 이전 데이터를 연결합니다.
// - 깊은 병합이 지원되는 경우 기본 요소가 더 이상 배열 유형이 아닐 때까지 flatten 메서드가 반복적으로 호출됩니다.
if(_.isArray(값))
return memo.concat(shallow ? value : _.Flatten(value));
// 데이터(값)가 이미 맨 아래에 있어서 더 이상 배열 형태가 아닌 경우, 해당 데이터를 메모에 병합하고 반환합니다.
메모[memo.length] = 값;
메모 반환;
}, []);
};
// 현재 배열에서 지정된 데이터와 동일하지 않은 차이 데이터를 필터링하여 반환합니다. (차이 방법 설명 참조)
_.without = 함수(배열) {
return _.difference(array, Slice.call(arguments, 1));
};
// 배열의 데이터 중복 제거(비교를 위해 === 사용)
// isSorted 매개변수가 false가 아닌 경우 배열의 요소에 대해 순차적으로 include 메소드를 호출하여 반환 값(배열)에 동일한 요소가 추가되었는지 확인합니다.
// 호출하기 전에 배열의 데이터가 순서대로 정렬되었는지 확인하면 isSorted를 true로 설정할 수 있습니다. isSorted를 사용하면 마지막 요소와 비교하여 동일한 값이 제외됩니다. .
// uniq 메소드는 기본적으로 배열의 데이터를 비교합니다. 반복기 프로세서가 선언된 경우 비교 배열은 프로세서를 기반으로 생성되지만 비교 중에 배열의 데이터만 반환됩니다. end는 여전히 원래 배열입니다.
_.uniq = _.unique = function(array, isSorted, iterator) {
// 반복자 프로세서를 사용하는 경우 현재 배열의 데이터가 반복자에 의해 먼저 처리되고 처리된 새 배열이 반환됩니다.
// 새 배열은 비교의 기초로 사용됩니다.
var 초기 = 반복자 ? _.map(array, iterator) : 배열;
// 처리 결과를 기록하는 데 사용되는 임시 배열
var 결과 = [];
// 배열에 값이 2개만 있는 경우 비교를 위해 include 메서드를 사용할 필요가 없습니다. isSorted를 true로 설정하면 작업 효율성이 향상됩니다.
if(array.length < 3)
isSorted = 사실;
// 처리 결과를 반복하고 누적하기 위해 축소 메소드를 사용합니다.
//초기 변수는 비교해야 하는 기준 데이터입니다. 원본 배열이거나 프로세서의 결과 집합일 수 있습니다(반복자가 설정된 경우).
_.reduce(초기, 함수(메모, 값, 인덱스) {
// isSorted 매개변수가 true인 경우 ===를 직접 사용하여 레코드의 마지막 데이터를 비교합니다.
// isSorted 매개변수가 false인 경우, include 메소드를 사용하여 컬렉션의 각 데이터와 비교합니다.
if( isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {
//메모는 비교된 중복되지 않은 데이터를 기록합니다.
// iterator 매개변수의 상태에 따라 메모에 기록되는 데이터는 원본 데이터일 수도 있고, 프로세서에서 처리된 데이터일 수도 있음
memo.push(값);
// 처리 결과 배열에 저장된 데이터는 항상 원래 배열의 데이터입니다.
results.push(배열[색인]);
}
메모 반환;
}, []);
//배열에 중복되지 않은 데이터만 포함된 처리 결과를 반환합니다.
결과를 반환합니다.
};
// Union 메소드는 uniq 메소드와 동일한 효과를 갖습니다. 차이점은 Union을 사용하면 여러 배열을 매개변수로 전달할 수 있다는 점입니다.
_.union = 함수() {
// Union은 매개변수의 여러 배열을 배열 객체로 얕게 병합하고 처리를 위해 uniq 메서드에 전달합니다.
return _.uniq(_.platten(arguments, true));
};
// 현재 배열과 하나 이상의 다른 배열의 교차 요소를 가져옵니다.
//두 번째 매개변수부터 시작하여 비교해야 하는 하나 이상의 배열입니다.
_.intersection = _.intersect = 함수(배열) {
// 나머지 변수는 비교해야 하는 다른 배열 객체를 기록합니다.
var 나머지 = Slice.call(인수, 1);
// 반복 계산을 피하기 위해 uniq 메소드를 사용하여 현재 배열에서 중복 데이터를 제거합니다.
// 프로세서를 통해 현재 배열의 데이터를 필터링하고 조건에 맞는 데이터를 반환합니다(동일 요소 비교).
return _.filter(_.uniq(array), function(item) {
// Every 메소드를 사용하여 각 배열에 비교해야 하는 데이터가 포함되어 있는지 확인합니다.
// 모든 배열에 비교 데이터가 포함되어 있으면 모두 true를 반환하고, 배열에 해당 요소가 없으면 false를 반환합니다.
return _.every(rest, function(other) {
// 다른 매개변수는 비교해야 하는 각 배열을 저장합니다.
// 항목은 현재 배열에서 비교해야 하는 데이터를 저장합니다.
// indexOf 메소드를 사용하여 배열에 해당 요소가 존재하는지 검색합니다. (indexOf 메소드 설명 참조)
return _.indexOf(기타, 항목) >= 0;
});
});
};
// 현재 배열에서 지정된 데이터와 동일하지 않은 차이 데이터를 필터링하고 반환합니다.
// 이 함수는 일반적으로 배열에서 지정된 데이터를 삭제하고 삭제 후 새 배열을 가져오는 데 사용됩니다.
// 이 메소드의 기능은 Without와 동일합니다. Without 메소드 매개변수는 데이터가 배열에 포함되는 것을 허용하지 않는 반면, Difference 메소드 매개변수는 배열을 권장합니다(without과 동일한 매개변수를 사용할 수도 있습니다).
_.차이 = 함수(배열) {
// 두 번째 매개변수부터 모든 매개변수를 배열로 병합합니다. (1단계만 병합하고, 깊은 병합은 하지 않습니다.)
// 나머지 변수에는 원본 데이터와 비교하기 위해 이 메서드에서 사용되는 검증 데이터가 저장됩니다.
var 나머지 = _.platten(slice.call(arguments, 1), true);
// 병합된 배열 데이터를 필터링합니다. 필터 조건은 현재 배열에 매개변수에 지정된 검증 데이터가 포함되어 있지 않다는 것입니다.
// 필터 조건에 맞는 데이터를 새로운 배열로 결합하여 반환
return _.filter(배열, 함수(값) {
return !_.include(나머지, 값);
});
};
//각 배열의 동일한 위치에 있는 데이터를 새로운 2차원 배열로 반환합니다. 반환되는 배열의 길이는 전달된 매개변수의 최대 배열 길이를 기준으로 합니다. 다른 배열의 공백 위치는 정의되지 않은 상태로 채워집니다.
// zip 메소드에는 여러 매개변수가 포함되어야 하며 각 매개변수는 배열이어야 합니다.
_.zip = 함수() {
//매개변수를 배열로 변환합니다. 이때 args는 2차원 배열입니다.
var args = Slice.call(인수);
// 각 배열의 길이를 계산하고 최대 길이 값을 반환합니다.
var 길이 = _.max(_.pluck(args, '길이'));
//처리 결과를 저장하는 데 사용되는 최대 길이 값에 따라 새로운 빈 배열을 생성합니다.
var 결과 = new Array(length);
//루프의 최대 길이, 각 루프에서 각 배열의 동일한 위치(0부터 순서대로 마지막 위치까지)의 데이터를 얻기 위해 pluck 메소드가 호출됩니다.
// 얻은 데이터를 새 배열에 저장하고 결과에 넣고 반환합니다.
for(var i = 0; i
로그인 후 복사