문제

항목이 희박한 요소 배열이 있습니다.데이터를 반복할 때마다 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;
});
.

데모.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top