更新 2018-09-07
在我看来,这个答案并不是很好。我在 如何从 JavaScript 对象中删除属性 上提供了一个答案,多年来得到了更多的关注,并覆盖了这种情况并进一步详细说明。
重点是,你应该使用 Array.prototype.splice
和 Array.prototype.slice
。
array.splice(start, n)
返回从索引 start
开始的连续 n
个元素的子集,并从原始数组中移除此子集,在此过程中创建一个新数组。
let array = [1,2,3,4,5,6];
array.splice(2,3); // [3,4,5]
array; // [1,2,6]
array.slice(start, end)
返回从索引 start
到索引 end
的子集,但不改变原始数组。这个方法的行为与 splice
有些不同,因此我更喜欢称它为 array.slice(start, start + n)
。
let array = [1,2,3,4,5,6];
array.slice(2, 2 + 3); // [3,4,5]
array; // [1,2,3,4,5,6]
当然,你可以将索引设置为类似于“null”或“”这样的哨兵值,但是如果你希望在删除后数组保持相同的顺序,也许应该改变你的方法——为什么“valuetwo”必须在索引1处?如果内容始终与访问它们所需的键相同,那么这个数据结构中甚至保存了什么有用的信息呢?
下面是原始答案。如果我要保留原始文本,也许我应该详细解释为什么这是错误的建议。
You can use javascript's delete
keyword.
delete array[index];
不要这样做。如果你的数组是同质的(应该是这样的),那么这样做会通过引入第二种类型(undefined
)来破坏你的数组。如上所述,你应该使用array.splice()
,它将创建一个新的数组,省略指定范围。
Unfortunately, this creates an undefined
index inside of the array
var arr = ['pie', 'cake', 'fish'];
delete arr[1];
arr; // ['pie', undefined, 'fish']
举个例子。
You could also do this:
var arr = [9,8,7,6];
arr[1] = null;
arr;
arr.length;
var i = -1;
while(++i < arr.length){
if(arr[i] && typeof(arr[i] === "number")){
alert(arr[i]);
}
}
你可以这样做,但是不应该。这不仅是不必要的,也没有任何有用的作用(因为它只是调用了alert),而且实际上是有问题的。
if(arr[i] && typeof(arr[i] === "number")){
alert(arr[i]);
}
您可能期望这只会在元素为非零数字时打印,但实际上它也会运行像
"foo"
,
[]
和
document.createElement("p")
这样的值,因为
typeof(arr[i] === "number")
总是返回值
"boolean"
,这是一个非空字符串,是真实的,因此将评估为true。这意味着唯一要求调用
alert
的条件是
arr[i]
是真实的。整个语言中只有六个值会导致此if语句不执行,它们是:
undefined
null
0
""
(发音为空字符串)false
NaN
Or, if you don't NEED to use arrays, you could use an object and make everything easier:
var obj = {
0: "first",
1: "second",
2: "third"
};
delete obj[1];
obj;
for(var i in obj){
alert(obj[i]);
}
这将立即抹掉使用数组的所有优势。现在你有了一个可能是异构的数据集,无法进行过滤、映射、约减或以任何明智的方式转换,你必须诉诸于像 for(i in obj)
这样的方法(如果你敢使用类似 jQuery 的库,则极易出现错误),来迭代它。幸运的是,今天我们有了像 Object.keys(obj).map(k => obj[k]).forEach(function(el){ ... })
这样的花哨东西,但这并不是拥有糟糕数据结构的借口。
To get the length of an object:
getLength = function(obj){
var i = 0, l = 0;
for(i in obj){
l++;
}
return l;
}
getLength(obj);
再次强调,对于数组来说,这是不必要的。
But remember that objects sort their indices by date of creation
, not > by name. This shouldn't result in a road block, though.
To sort the indices of an object alphabetically:
sortObject = function (){
var arr = [], i;
for(i in this){
arr.push({index:i,content:this[i]});
delete this[i];
}
arr.sort();
for(i in arr){
var item = arr[i];
this[item.index] = item.content;
}
return this;
}
var obj = {
acronym: "OOP",
definition: "Object-Oriented Programming",
article: "http://wikipedia.org/OOP"
};
sortObject.apply(obj);
array.sort(fn)
整个对象的意义在于其属性是未排序的。对未排序的列表进行排序几乎没有任何有用的作用。
只是为了说明数组在执行数组操作方面要好得多:
let array = ["pie", "cake", "fish", "brownie", "beef", ...];
array
.filter(el => exclude.indexOf(el) === -1)
.forEach(function(el){
console.log(el);
});
如果
exclude
是
["cake", "brownie"]
,那么它将记录以下内容到控制台:
pie
fish
beef
...
试着想象一下,如果使用上一个答案中的方法来做同样的事情,需要多少不必要的代码行。
希望这有所帮助。
希望这个更新能够有所帮助。