[英]Condensing a sparse array in Javascript?
我有一個元素數組,其中條目稀疏。 如何輕松地將稀疏數組壓縮為密集數組,以便每次遍歷數據時都不必繼續檢查 null 和 undefined 值?
以下是一些示例數據:
var sparse = [];
sparse[1] = undefined;
sparse[5] = 3;
sparse[10] = null;
var dense = sparseToDenseArray(sparse);
// dense should be [3]
您可以使用與 Firefox、Chrome、IE 9、Opera 和 Safari 網絡瀏覽器兼容的filter()
。
根據 David Flanagan 的說法,在Javascript: The Definitive Guide 中,將稀疏數組轉換為密集數組的一種簡單方法是在其上使用過濾器,如下所示:
var dense = sparse.filter(function (x) { return x !== undefined && x != null; });
這是有效的,因為filter()
跳過缺少的元素,並且僅在 x 不是undefined
或null
時才返回true
。
如果不支持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);
請注意,此方法僅刪除gaps ,根據需要向下移動現有數組元素的索引。 它不會刪除顯式設置為undefined
或null
元素。
在 vanilla 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]
如果你想在你的代碼中包含 underscore.js,你可以在你的數組上使用compact函數。
我不敢相信這里的答案如此有限。 首先,我認為有更好、更快的解決方案來壓縮稀疏數組。 我猜一個稀疏數組並不意味着一個帶有未定義項孔的數組(究竟什么是密集數組? )。 稀疏數組應該是一個數組,其中除了屬於現有但稀疏值的鍵之外,實際上不存在任何鍵。 因此,如果我們迭代鍵,我們應該更有效、更快地完成我們的工作。
好的,我在下面編譯了一個測試,向您展示了幾種壓縮稀疏數組的方法的性能。
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");
filter 是 ECMA-262 標准的 JavaScript 擴展; 因此,它可能不會出現在標准的其他實現中。 您可以通過在腳本的開頭插入以下代碼來解決此問題,允許在本機不支持它的 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 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.