두 개의 배열이 있습니다. 첫 번째 배열에는 일부 값이 포함되고 두 번째 배열에는 첫 번째 배열에서 제거되어야하는 값의 인덱스가 포함됩니다. 예를 들면 :
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
나는 인덱스에 값 선물을 제거 할 0,2,4
에서 valuesArr
. 기본 splice
방법이 도움이 될 것이라고 생각하여 다음과 같이 생각해 냈습니다.
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
그러나 각마다 splice
값의 인덱스 valuesArr
가 다르기 때문에 작동하지 않았습니다 . 임시 배열을 사용하고 모든 값을 두 번째 배열에 복사하여이 문제를 해결할 수 있지만 배열에서 값을 제거 할 여러 인덱스를 전달할 수있는 네이티브 메서드가 있는지 궁금합니다.
jQuery 솔루션을 선호합니다. ( grep
여기에서 사용할 수 있는지 확실하지 않음 )
답변
항상 평범한 오래된 for
루프가 있습니다.
var valuesArr = ["v1","v2","v3","v4","v5"],
removeValFromIndex = [0,2,4];
for (var i = removeValFromIndex.length -1; i >= 0; i--)
valuesArr.splice(removeValFromIndex[i],1);
를 통해 이동 removeValFromIndex
역순으로하고 있습니다 .splice()
아직 – 투 – 제거 할 항목의 인덱스를 엉망으로하지 않고.
위의 내용에서 대괄호가있는 array-literal 구문을 사용하여 두 배열을 선언했습니다. new Array()
전달하는 매개 변수 수에 따라 다르게 응답 하므로 사용이 잠재적으로 혼란 스럽기 때문에 권장되는 구문 입니다.
편집 : 특정 순서가 아닌 인덱스 배열에 대한 다른 답변에 대한 귀하의 의견을 보았습니다. 이 경우 시작하기 전에 내림차순으로 정렬하십시오.
removeValFromIndex.sort(function(a,b){ return b - a; });
그리고 $.each()
당신이 좋아 하는 루핑 / / 등 방법으로 그것을 따르십시오 .
답변
다음은 lodash / underscore를 사용하지 않을 때 사용하는 것입니다.
while(IndexesToBeRemoved.length) {
elements.splice(IndexesToBeRemoved.pop(), 1);
}
답변
아닙니다 .의 및 기능을 in-place
사용하여 수행 할 수 있습니다 .grep
inArray
jQuery
var arr = $.grep(valuesArr, function(n, i) {
return $.inArray(i, removeValFromIndex) ==-1;
});
alert(arr);//arr contains V2, V4
답변
Array.prototype.filter 를 사용하는 것이 좋습니다.
var valuesArr = ["v1","v2","v3","v4","v5"];
var removeValFrom = [0, 2, 4];
valuesArr = valuesArr.filter(function(value, index) {
return removeValFrom.indexOf(index) == -1;
})
답변
function filtermethod(element, index, array) {
return removeValFromIndex.find(index)
}
var result = valuesArr.filter(filtermethod);
MDN 참조는 여기
답변
순수 JS에서는 배열을 거꾸로 반복 할 수 있으므로 루프에서 splice()
다음 요소의 인덱스를 엉망으로 만들지 않습니다.
for (var i = arr.length - 1; i >= 0; i--) {
if ( yuck(arr[i]) ) {
arr.splice(i, 1);
}
}
답변
O(n)
시간 과 함께 답변을 게시 할 필요가 있다고 느낍니다 :). 스플 라이스 솔루션의 문제점은 배열의 기본 구현이 문자 그대로 배열이기 때문에 각 splice
호출에 O(n)
시간 이 걸린다는 것 입니다. 이 동작을 악용하는 예제를 설정할 때 가장 두드러집니다.
var n = 100
var xs = []
for(var i=0; i<n;i++)
xs.push(i)
var is = []
for(var i=n/2-1; i>=0;i--)
is.push(i)
이것은 중간에서 시작으로 요소를 제거하므로 제거 할 때마다 js 엔진이 n/2
요소 를 복사하도록 강제합니다 (n/2)^2
. 총 복사 작업은 2 차입니다.
스플 라이스 솔루션 ( is
오버 헤드를 제거하기 위해 이미 내림차순으로 정렬 되었다고 가정 )은 다음과 같습니다.
for(var i=0; i<is.length; i++)
xs.splice(is[i], 1)
그러나 처음부터 배열을 재구성하고 마스크를 사용하여 요소를 복사하는지 여부를 확인하여 선형 시간 솔루션을 구현하는 것은 어렵지 않습니다 (정렬은이를로 푸시합니다 O(n)log(n)
). 다음은 그러한 구현입니다 ( mask
속도를 위해 부울 반전 되지 않음 ).
var mask = new Array(xs.length)
for(var i=is.length - 1; i>=0; i--)
mask[is[i]] = true
var offset = 0
for(var i=0; i<xs.length; i++){
if(mask[i] === undefined){
xs[offset] = xs[i]
offset++
}
}
xs.length = offset
나는 이것을 jsperf.com 에서 실행 했고 심지어 n=100
스플 라이스 방법도 완전히 90 % 느리다. 더 클수록 n
이 차이는 훨씬 더 클 것입니다.
