我具有其中条目是稀疏元件的阵列。 我怎么能轻易凝聚稀疏数组密集排列,这样我就没有继续检查null和undefined值通过数据我每次循环?
下面是一些示例数据:
var sparse = [];
sparse[1] = undefined;
sparse[5] = 3;
sparse[10] = null;
var dense = sparseToDenseArray(sparse);
// dense should be [3]
我具有其中条目是稀疏元件的阵列。 我怎么能轻易凝聚稀疏数组密集排列,这样我就没有继续检查null和undefined值通过数据我每次循环?
下面是一些示例数据:
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()
这是火狐,Chrome,IE 9,Opera和Safari网页浏览器兼容。
据大卫·弗拉纳根,在Javascript权威指南 ,转化稀疏阵列密集排列的一种简单的方法是使用过滤器就可以了,像这样:
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,您可以使用紧凑阵列上的功能。
我不相信有这样的答案在有限这里。 首先,我认为有更好,更快地凝结稀疏阵列的解决方案。 我想一个稀疏数组并不意味着赞同不确定项孔的阵列( 到底是什么密集阵? )。 稀疏阵列应该在哪里实际上没有比键属于现有但稀疏值项中是否存在其他的阵列。 因此,如果我们遍历键,我们应得到更有效和更快的做我们的工作。
好吧,我编译下面的测试向您展示的几种方法的性能凝聚稀疏数组。
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");
滤波器是一个JavaScript扩展,ECMA-262标准; 因此它可以不存在在该标准的其他实现方式。 您可以通过在你的脚本的开头插入下面的代码,允许其本身不支持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;
});
DEMO。