如何从数组中删除一个特定值? 类似 :
array.remove(value);
我必须使用核心核心核心JavaScript。 不允许框架 。
如何从数组中删除一个特定值? 类似 :
array.remove(value);
我必须使用核心核心核心JavaScript。 不允许框架 。
当前回答
删除上次的元素
arrName.pop();
删除第一个元素
arrName.shift();
从中间删除
arrName.splice(starting index, number of element you wnt to delete);
Example: arrName.splice(1, 1);
删除最后一个元素
arrName.splice(-1);
使用数组索引编号删除
delete arrName[1];
其他回答
2017-05-08
大多数给定的回答都用于严格的比较, 意思是两个对象在内存( 或原始类型) 中引用完全相同的对象, 但通常您想要从具有一定值的数组中删除一个非原始对象。 例如, 如果您给服务器打电话, 并想要对照本地对象检查已检索到的对象 。
const a = {'field': 2} // Non-primitive object
const b = {'field': 2} // Non-primitive object with same value
const c = a // Non-primitive object that reference the same object as "a"
assert(a !== b) // Don't reference the same item, but have same value
assert(a === c) // Do reference the same item, and have same value (naturally)
//Note: there are many alternative implementations for valuesAreEqual
function valuesAreEqual (x, y) {
return JSON.stringify(x) === JSON.stringify(y)
}
//filter will delete false values
//Thus, we want to return "false" if the item
// we want to delete is equal to the item in the array
function removeFromArray(arr, toDelete){
return arr.filter(target => {return !valuesAreEqual(toDelete, target)})
}
const exampleArray = [a, b, b, c, a, {'field': 2}, {'field': 90}];
const resultArray = removeFromArray(exampleArray, a);
//resultArray = [{'field':90}]
数值AreEqual有替代/更快的操作,但这样可以操作。如果您有特定的字段要检查,也可以使用自定义的比较器(例如,有些已检索的 UUID 相对于本地的 UUID ) 。
2. 还注意到这是一个功能操作,意即它不改变原始阵列。
主要有两种办法:
复数(): anArray.splice(index, 1);
let fruits = ['Apple', 'Banana', 'Mango', 'Orange']
let removed = fruits.splice(2, 1);
// fruits is ['Apple', 'Banana', 'Orange']
// removed is ['Mango']
删除删除: delete anArray[index];
let fruits = ['Apple', 'Banana', 'Mango', 'Orange']
let removed = delete fruits(2);
// fruits is ['Apple', 'Banana', undefined, 'Orange']
// removed is true
使用时要小心delete
用于对数组的数组。它有利于删除对象的属性,但对于数组则不那么好。最好使用splice
用于数组。
请注意,当使用delete
对于一个数组,您可能会获得错误的结果anArray.length
换句话说,delete
将会删除元素, 但它不会更新长度属性的值 。
使用删除后,也可以期望在索引编号上出现空洞,例如,最后可能会有第1、3、4、8、9和11号指数,而之前的长度与使用删除时相同。for
循环会崩溃, 因为索引不再是相继的 。
被迫使用delete
出于某种原因,你应该使用for each
需要通过数组循环时循环循环。事实上,总是避免使用索引for
如果可能的话,循环。这样代码就会更稳健,更不易遇到指数问题。
我建议删除一个使用删除和过滤的阵列项目:
var arr = [1,2,3,4,5,5,6,7,8,9];
delete arr[5];
arr = arr.filter(function(item){ return item != undefined; });
//result: [1,2,3,4,5,6,7,8,9]
console.log(arr)
因此,我们只能删除一个特定的数组项目,而不是所有具有相同价值的项目。
约翰·里维格( John Resig)已张贴良好执行情况:
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
如果您不想扩展一个全球对象, 可以做一些类似的东西,
// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
var rest = array.slice((to || from) + 1 || array.length);
array.length = from < 0 ? array.length + from : from;
return array.push.apply(array, rest);
};
但我之所以张贴这篇文章,主要是为了提醒用户不要采取该页(2007年12月14日)评论中建议的其他实施方式:
Array.prototype.remove = function(from, to) {
this.splice(from, (to=[0, from || 1, ++to - from][arguments.length]) < 0 ? this.length + to : to);
return this.length;
};
它一开始似乎效果良好,但经过一个痛苦的过程,我发现它在试图删除数组中第二至最后一个元素时失败了。例如,如果您有一个 10 元素数组,并且试图用这个来删除第九元素:
myArray.remove(8);
我不知道为什么 但我确认约翰的原创执行没有问题
根据所有主要正确的答复并考虑到建议的最佳做法(特别是不直接使用Array.prototype),我提出了以下代码:
function arrayWithout(arr, values) {
var isArray = function(canBeArray) {
if (Array.isArray) {
return Array.isArray(canBeArray);
}
return Object.prototype.toString.call(canBeArray) === '[object Array]';
};
var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
var arrCopy = arr.slice(0);
for (var i = arrCopy.length - 1; i >= 0; i--) {
if (excludedValues.indexOf(arrCopy[i]) > -1) {
arrCopy.splice(i, 1);
}
}
return arrCopy;
}
在审查上述功能时,尽管运作良好,但我意识到业绩可能有所改进。 使用ES6而不是ES5是一种更好的方法。
const arrayWithoutFastest = (() => {
const isArray = canBeArray => ('isArray' in Array)
? Array.isArray(canBeArray)
: Object.prototype.toString.call(canBeArray) === '[object Array]';
let mapIncludes = (map, key) => map.has(key);
let objectIncludes = (obj, key) => key in obj;
let includes;
function arrayWithoutFastest(arr, ...thisArgs) {
let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;
if (typeof Map !== 'undefined') {
withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
includes = mapIncludes;
} else {
withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {});
includes = objectIncludes;
}
const arrCopy = [];
const length = arr.length;
for (let i = 0; i < length; i++) {
// If value is not in exclude list
if (!includes(withoutValues, arr[i])) {
arrCopy.push(arr[i]);
}
}
return arrCopy;
}
return arrayWithoutFastest;
})();
如何使用 :
const arr = [1,2,3,4,5,"name", false];
arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)
我目前正在写博客文章, 其中我已设定数个无问题的阵列解决方案基准, 并比较运行时间。 一旦我完成此文章, 我将更新此答案, 并用链接更新。 仅供参考, 我比较了上述与没有 Lodash 的比较, 以防浏览器支持Map
注意我没有用Array.prototype.indexOf
或Array.prototype.includes
将exlcude Values 包装在Map
或Object
让查询更快!