Javascript에서 희소 배열을 압축하시겠습니까?
-
11-12-2019 - |
문제
항목이 희박한 요소 배열이 있습니다.데이터를 반복할 때마다 null 및 정의되지 않은 값을 계속 확인할 필요가 없도록 희소 배열을 조밀한 배열로 쉽게 압축하려면 어떻게 해야 합니까?
다음은 몇 가지 예시 데이터입니다.
var sparse = [];
sparse[1] = undefined;
sparse[5] = 3;
sparse[10] = null;
var dense = sparseToDenseArray(sparse);
// dense should be [3]
해결책
바닐라 JS에서 모든 브라우저에서 작동합니다 :
function filt(a) {
var b = [];
for(var i = 0;i < a.length;i++) {
if (a[i] !== undefined && a[i] !== null) {
b.push(a[i]);
}
}
return b;
}
> filt([1,undefined,3])
[1, 3]
. 다른 팁
당신이 사용할 수있는 filter()
Firefox, Chrome, IE 9, Opera 및 Safari 웹 브라우저와 호환됩니다.
데이비드 플래너건(David Flanagan)에 따르면, 자바스크립트:최종 가이드, 희소 배열을 조밀한 배열로 변환하는 쉬운 방법은 다음과 같이 필터를 사용하는 것입니다.
var dense = sparse.filter(function (x) { return x !== undefined && x != null; });
이것은 이후로 작동합니다 filter()
누락된 요소를 건너뛰고 반환만 반환합니다. true
x가 아니라면 undefined
또는 null
.
만약에 filter()
지원되지 않으면 희소 배열이 압축됩니다.
var compacted = [];
for(var i = 0; i < sparse.length; i++)
if(i in sparse)
compacted.push(sparse[i]);
의 정확한 동일 filter()
예는 다음과 같습니다
var compacted = [];
for(var i = 0; i < sparse.length; i++)
if(sparse[i] != null)
compacted.push(sparse[i]);
ES2017(ES8)에서는 다음과 같이 쉽습니다. Object.values(sparseArray)
예를 들어:
const sparseArray = [, , 'foo', 'bar', , 'baz', ,];
const compactArray = Object.values(sparseArray);
console.log(compactArray);
이 방법은 단지 제거만 한다는 점에 유의하세요. 틈, 필요에 따라 기존 배열 요소의 인덱스를 아래로 이동합니다.명시적으로 설정된 요소는 제거되지 않습니다. undefined
또는 null
.
코드에 underscore.js를 포함 시키려면 배열에서 컴팩트 기능을 사용할 수 있습니다..
여기에 제한된 답변이 있음을 믿을 수 없습니다.우선, 스파 스 배열을 응축시키는 것이 더 빠른 솔루션이 있다고 생각합니다.나는 절삭 배열이 정의되지 않은 항목의 구멍이있는 배열을 의미하지 않는다고 생각합니다 ( 정확히 조밀 한 배열이란 무엇입니까? ).스파 스 배열은 실제로 기존하지만 희소 한 값에 속한 키가 아닌 다른 키가없는 배열이어야합니다.따라서 우리가 열쇠를 반복하면 우리의 일을보다 효율적이고 더 빨리하고 있어야합니다.
OK 나는 스파 스 배열을 응축시키는 몇 가지 방법의 성능을 보여주기 위해 아래의 테스트를 작성했습니다.
var ts = 0,
te = 0,
sparse = new Array(10000000),
dense = [];
[sparse[2499999], sparse[4999999], sparse[9999999]] = ["first one", "middle one", "last one"];
ts = performance.now();
dense = Object.keys(sparse).map(k => sparse[k]);
te = performance.now();
console.log(dense, "Okeys and map resulted in :" +(te-ts)+ "msecs");
dense = [];
ts = performance.now();
for (var key in sparse) dense.push(sparse[key]);
te = performance.now();
console.log(dense, "for in loop resulted in :" +(te-ts)+ "msecs");
dense = [];
ts = performance.now();
dense = sparse.filter(function (x) { return x !== undefined && x !== null; });
te = performance.now();
console.log(dense, "Array filter resulted in :" +(te-ts)+ "msecs");
dense = [];
ts = performance.now();
for (var i = 0, len = sparse.length; i < len; i++) sparse[i] !== undefined &&
sparse[i] !== null &&
dense.push(sparse[i]);
te = performance.now();
console.log(dense, "For loop resulted in :" +(te-ts)+ "msecs");
.
필터는 ECMA-262 표준에 대한 자바 스크립트 확장입니다.그런 것으로 표준의 다른 구현에서는 존재하지 않을 수 있습니다.당신은 할 수 있습니다 다음 코드를 삽입 하여이 작업을 수행하십시오. Scripts, ECMA-262 구현에서 필터를 사용할 수 있습니다. 기본적으로 그것을 지원하지 마십시오.참고 : mdn .
filter
를 사용하는 크로스 브라우저 솔루션.if (!Array.prototype.filter) { // Add the filter method to the 'Array prototype' if it's not available Array.prototype.filter = function(fun /*, thisp*/) { var len = this.length >>> 0; if (typeof fun != "function") { throw new TypeError(); } var res = []; var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) { var val = this[i]; if (fun.call(thisp, val, i, this)) { res.push(val); } } } return res; }; } var sparse = []; sparse[1] = undefined; sparse[5] = 3; sparse[10] = null; dense=sparse.filter(function(a){ //Call the `filter` method return a!== undefined && a != null; });