Làm cách nào để xóa các phần tử trống khỏi một mảng trong JavaScript?
Có một cách đơn giản, hoặc tôi cần phải lặp qua nó và loại bỏ chúng bằng tay?
Làm cách nào để xóa các phần tử trống khỏi một mảng trong JavaScript?
Có một cách đơn giản, hoặc tôi cần phải lặp qua nó và loại bỏ chúng bằng tay?
Câu trả lời:
EDIT: Câu hỏi này đã được trả lời gần chín năm trước khi không có nhiều phương pháp tích hợp hữu ích trong Array.prototype
.
Bây giờ, chắc chắn, tôi sẽ khuyên bạn nên sử dụng filter
phương pháp này.
Hãy nhớ rằng phương thức này sẽ trả về cho bạn một mảng mới với các phần tử vượt qua các tiêu chí của hàm gọi lại mà bạn cung cấp cho nó.
Ví dụ: nếu bạn muốn xóa null
hoặc undefined
giá trị:
var array = [0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,,];
var filtered = array.filter(function (el) {
return el != null;
});
console.log(filtered);
Nó sẽ phụ thuộc vào những gì bạn coi là "trống", ví dụ, nếu bạn đang xử lý các chuỗi, hàm trên sẽ không loại bỏ các phần tử là một chuỗi rỗng.
Một mô hình điển hình mà tôi thấy thường được sử dụng là để loại bỏ các yếu tố đó là falsy , trong đó bao gồm một chuỗi rỗng ""
, 0
, NaN
, null
, undefined
, và false
.
Bạn có thể chuyển đến filter
phương thức, Boolean
hàm xây dựng hoặc trả về cùng một phần tử trong hàm tiêu chí lọc, ví dụ:
var filtered = array.filter(Boolean);
Hoặc là
var filtered = array.filter(function(el) { return el; });
Trong cả hai cách, điều này hoạt động vì filter
phương thức trong trường hợp đầu tiên, gọi hàm Boolean
tạo là hàm, chuyển đổi giá trị và trong trường hợp thứ hai, filter
phương thức bên trong biến giá trị trả về của hàm gọi lại thành ngầm định Boolean
.
Nếu bạn đang làm việc với các mảng thưa thớt và bạn đang cố gắng thoát khỏi các "lỗ hổng", bạn có thể sử dụng filter
phương thức chuyển một cuộc gọi lại trả về true, ví dụ:
var sparseArray = [0, , , 1, , , , , 2, , , , 3],
cleanArray = sparseArray.filter(function () { return true });
console.log(cleanArray); // [ 0, 1, 2, 3 ]
Câu trả lời cũ: Đừng làm điều này!
Tôi sử dụng phương pháp này, mở rộng nguyên mẫu Array gốc:
Array.prototype.clean = function(deleteValue) {
for (var i = 0; i < this.length; i++) {
if (this[i] == deleteValue) {
this.splice(i, 1);
i--;
}
}
return this;
};
test = new Array("", "One", "Two", "", "Three", "", "Four").clean("");
test2 = [1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,];
test2.clean(undefined);
Hoặc bạn có thể chỉ cần đẩy các phần tử hiện có vào mảng khác:
// Will remove all falsy values: undefined, null, 0, false, NaN and "" (empty string)
function cleanArray(actual) {
var newArray = new Array();
for (var i = 0; i < actual.length; i++) {
if (actual[i]) {
newArray.push(actual[i]);
}
}
return newArray;
}
cleanArray([1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,]);
splice
gọi thực sự tốn kém trên các trình duyệt cũ hơn vì chúng phải đánh số lại tất cả các phím mảng để thu hẹp khoảng cách.
Array.prototype
bằng cách sử dụng Object.defineProperty
chức năng mới thành một thuộc tính không thể đếm được và sau đó tránh được hiệu năng gây ra bằng cách đặt .hasOwnProperty
vào mỗi vòng lặp.
var arr = [1,2,,3,,-3,null,,0,,undefined,4,,4,,5,,6,,,,];
arr.filter(n => n)
// [1, 2, 3, -3, 4, 4, 5, 6]
arr.filter(Number)
// [1, 2, 3, -3, 4, 4, 5, 6]
arr.filter(Boolean)
// [1, 2, 3, -3, 4, 4, 5, 6]
hoặc - (chỉ dành cho các mục mảng đơn loại "văn bản")
['','1','2',3,,'4',,undefined,,,'5'].join('').split('');
// output: ["1","2","3","4","5"]
hoặc - Cách cổ điển: lặp đơn giản
var arr = [1,2,null, undefined,3,,3,,,0,,,[],,{},,5,,6,,,,],
len = arr.length, i;
for(i = 0; i < len; i++ )
arr[i] && arr.push(arr[i]); // copy non-empty values to the end of the array
arr.splice(0 , len); // cut the array and leave only the non-empty values
arr // [1,2,3,3,[],Object{},5,6]
var arr = [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,];
arr = $.grep(arr,function(n){ return n == 0 || n });
arr // [1, 2, 3, 3, 0, 4, 4, 5, 6]
var arr = [1,2,null, undefined,3,,3,,,0,,,4,,4,,5,,6,,,,],
temp = [];
for(let i of arr)
i && temp.push(i); // copy each non-empty value to the 'temp' array
arr = temp;
arr // [1, 2, 3, 3, 4, 4, 5, 6]
['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)
// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
arr = arr.filter(function(n){return n; });
foo.join("").split("")
dường như chỉ hoạt động nếu các chuỗi là các ký tự đơn
arr.filter(e=>e)
và điều này có thể được xâu chuỗi bằng bản đồ, thu nhỏ, v.v.
Nếu bạn cần xóa TẤT CẢ các giá trị trống ("", null, không xác định và 0):
arr = arr.filter(function(e){return e});
Để xóa các giá trị trống và ngắt dòng:
arr = arr.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});
Thí dụ:
arr = ["hello",0,"",null,undefined,1,100," "]
arr.filter(function(e){return e});
Trở về:
["hello", 1, 100, " "]
CẬP NHẬT (dựa trên nhận xét của Alnitak)
Trong một số trường hợp, bạn có thể muốn giữ "0" trong mảng và xóa mọi thứ khác (null, không xác định và ""), đây là một cách:
arr.filter(function(e){ return e === 0 || e });
Trở về:
["hello", 0, 1, 100, " "]
function(e){return !!e}
!!e
sẽ bao gồm NaN (không giống 0) trong e
đó sẽ không (như 0).
var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);
loại bỏ không xác định, "" và 0
Đơn giản chỉ cần một lớp lót:
[1, false, "", undefined, 2].filter(Boolean); // [1, 2]
hoặc sử dụng underscorejs.org :
_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
Boolean
hoạt động như một chức năng ...
Boolean
như là một hàm, nó sẽ chỉ trả về true
hoặc làm false
giảm giá trị thực sự / giả.
(true).constructor === Boolean
. Và sau đó cho tôi biết nếu chúng ta có thể làm điều này với các bản dựng khác trong JS. ;)) (Tất nhiên excluted khác 5 build-in constructors (String, Array, Object, Function, Số)).
Nếu bạn đã có Javascript 1.6 trở lên, bạn có thể sử Array.filter
dụng return true
chức năng gọi lại tầm thường , ví dụ:
arr = arr.filter(function() { return true; });
kể từ khi .filter
tự động bỏ qua các phần tử bị thiếu trong mảng ban đầu.
Trang MDN được liên kết ở trên cũng chứa một phiên bản kiểm tra lỗi đẹp filter
có thể được sử dụng trong các trình thông dịch JavaScript không hỗ trợ phiên bản chính thức.
Lưu ý rằng điều này sẽ không xóa null
các mục nhập cũng như các mục có undefined
giá trị rõ ràng , nhưng OP đặc biệt yêu cầu các mục "thiếu".
undefined
giá trị nhất định.
Để loại bỏ lỗ, bạn nên sử dụng
arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this
Để xóa lỗ và các giá trị giả (null, không xác định, 0, -0, NaN, "", false, document.all):
arr.filter(x => x)
Để xóa lỗ, null và không xác định:
arr.filter(x => x != null)
arr = [, null, (void 0), 0, -0, NaN, false, '', 42];
console.log(arr.filter(() => true)); // [null, (void 0), 0, -0, NaN, false, '', 42]
console.log(arr.filter(x => x)); // [42]
console.log(arr.filter(x => x != null)); // [0, -0, NaN, false, "", 42]
[, ,]
arr.filter(x => x)
, JS sẽ kiểm tra xem x là trung thực hay giả if (x)
, do đó, chỉ có giá trị trung thực sẽ được gán cho danh sách mới.
Cách sạch sẽ để làm điều đó.
var arr = [0,1,2,"Thomas","false",false,true,null,3,4,undefined,5,"end"];
arr = arr.filter(Boolean);
// [1, 2, "Thomas", "false", true, 3, 4, 5, "end"]
undefined
; điều này về cơ bản loại bỏ tất cả các giá trị giả.
Với gạch dưới / dấu gạch ngang:
Trường hợp sử dụng chung:
_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
Với trống rỗng:
_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]
Nếu sử dụng thư viện là một tùy chọn tôi biết underscore.js có một hàm gọi là compact () http://documentcloud.github.com/underscore/, nó cũng có một số hàm hữu ích khác liên quan đến mảng và bộ sưu tập.
Đây là một đoạn trích từ tài liệu của họ:
_.compact (mảng)
Trả về một bản sao của mảng với tất cả các giá trị sai lệch được loại bỏ. Trong JavaScript, false, null, 0, "", không xác định và NaN đều sai.
_.compact ([0, 1, sai, 2, '', 3]);
=> [1, 2, 3]
@ Alititak
Trên thực tế Array.filter hoạt động trên tất cả các trình duyệt nếu bạn thêm một số mã bổ sung. Xem bên dưới.
var array = ["","one",0,"",null,0,1,2,4,"two"];
function isempty(x){
if(x!=="")
return true;
}
var res = array.filter(isempty);
document.writeln(res.toJSONString());
// gives: ["one",0,null,0,1,2,4,"two"]
Đây là mã bạn cần thêm cho IE, nhưng bộ lọc và lập trình hàm có giá trị là imo.
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
{
var val = this[i]; // in case fun mutates this
if (fun.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}
let newArr = arr.filter(e => e);
Bạn có thể thấy việc lặp lại mảng của mình dễ dàng hơn và xây dựng một mảng mới trong số các mục bạn muốn giữ khỏi mảng hơn là cố gắng lặp và ghép như đã được đề xuất, vì sửa đổi độ dài của mảng trong khi nó đang được lặp trên có thể giới thiệu vấn đề.
Bạn có thể làm một cái gì đó như thế này:
function removeFalsyElementsFromArray(someArray) {
var newArray = [];
for(var index = 0; index < someArray.length; index++) {
if(someArray[index]) {
newArray.push(someArray[index]);
}
}
return newArray;
}
Trên thực tế đây là một giải pháp chung chung hơn:
function removeElementsFromArray(someArray, filter) {
var newArray = [];
for(var index = 0; index < someArray.length; index++) {
if(filter(someArray[index]) == false) {
newArray.push(someArray[index]);
}
}
return newArray;
}
// then provide one or more filter functions that will
// filter out the elements based on some condition:
function isNullOrUndefined(item) {
return (item == null || typeof(item) == "undefined");
}
// then call the function like this:
var myArray = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,];
var results = removeElementsFromArray(myArray, isNullOrUndefined);
// results == [1,2,3,3,4,4,5,6]
Bạn có ý tưởng - sau đó bạn có thể có các loại chức năng lọc khác. Có lẽ nhiều hơn bạn cần, nhưng tôi đã cảm thấy hào phóng ...;)
Bạn nên sử dụng bộ lọc để lấy mảng mà không có phần tử trống. Ví dụ về ES6
const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
Tôi chỉ đơn giản là góp thêm tiếng nói của tôi để ở trên “gọi ES5 của Array..filter()
một nhà xây dựng toàn cầu” golf-hack, nhưng tôi đề nghị sử dụng Object
thay vì String
, Boolean
hoặc Number
theo đề nghị trên.
Cụ thể, ES5 filter()
đã không kích hoạt các undefined
phần tử trong mảng; do đó, một hàm trả về toàn cầu true
, trả về tất cả các filter()
lần truy cập phần tử , sẽ nhất thiết chỉ trả về các undefined
phần tử không :
> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(function(){return true})
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]
Tuy nhiên, viết ra ...(function(){return true;})
dài hơn viết ...(Object)
; và giá trị trả về của hàm Object
tạo sẽ, trong mọi trường hợp , một số loại đối tượng. Không giống như các nhà xây dựng quyền anh nguyên thủy được đề xuất ở trên, không có giá trị đối tượng nào có thể là falsey, và do đó, trong một khung cảnh boolean, Object
là một cách ngắn gọn function(){return true}
.
> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(Object)
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]
someArray.filter(String);
là tương đương với someArray.filter(function(x){ return String(x); });
. Nếu bạn muốn xóa tất cả các giá trị giả sẽ someArray.filter(Boolean);
hoạt động để xóa 0, -0, NaN, false, '', null và không xác định.
Object
tạo trái ngược với return true
phương thức. @robocat OP yêu cầu xóa các phần tử trống, không phải null.
Khi sử dụng câu trả lời được bình chọn cao nhất ở trên, ví dụ đầu tiên, tôi đã nhận được các ký tự riêng lẻ cho độ dài chuỗi lớn hơn 1. Dưới đây là giải pháp của tôi cho vấn đề đó.
var stringObject = ["", "some string yay", "", "", "Other string yay"];
stringObject = stringObject.filter(function(n){ return n.length > 0});
Thay vì không quay lại nếu không xác định, chúng tôi quay lại nếu chiều dài lớn hơn 0. Hy vọng điều đó sẽ giúp ai đó ngoài kia.
Trả về
["some string yay", "Other string yay"]
["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123
Thay thế hàm đó. .. với String, trớ trêu thay, để lại số nhưng sẽ cho kết quả tương tự trong mảng đã cho của bạn.
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r)
[1,2,3]
Thế còn
js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
join() === join(',')
:)
Điều này hoạt động, tôi đã thử nghiệm nó trong AppJet (bạn có thể sao chép-dán mã trên IDE của nó và nhấn "tải lại" để xem nó hoạt động, không cần tạo tài khoản)
/* appjet:version 0.1 */
function Joes_remove(someArray) {
var newArray = [];
var element;
for( element in someArray){
if(someArray[element]!=undefined ) {
newArray.push(someArray[element]);
}
}
return newArray;
}
var myArray2 = [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,];
print("Original array:", myArray2);
print("Clenased array:", Joes_remove(myArray2) );
/*
Returns: [1,2,3,3,0,4,4,5,6]
*/
for ... in
đó thực sự gây ra việc bỏ qua các yếu tố bị thiếu. Thử nghiệm undefined
chỉ phục vụ để loại bỏ các yếu tố thực được đặt rõ ràng thành giá trị đó.
Một cách khác để làm điều đó là tận dụng thuộc tính độ dài của mảng: đóng gói các mục không null vào 'bên trái' của mảng, sau đó giảm độ dài. Đây là một thuật toán tại chỗ - không phân bổ bộ nhớ, quá tệ cho trình thu gom rác - và nó có hành vi trường hợp tốt nhất / trung bình / tồi tệ nhất.
Giải pháp này, so với các giải pháp khác ở đây, nhanh hơn từ 2 đến 50 lần trên Chrome và nhanh hơn 5 đến 50 lần trên Firefox, như bạn có thể thấy ở đây: http://jsperf.com/remove-null-items-from-array
Đoạn mã dưới đây thêm phương thức 'removeNull' không thể đếm được vào Mảng, trả về 'this' cho chuỗi daisy:
var removeNull = function() {
var nullCount = 0 ;
var length = this.length ;
for (var i=0, len=this.length; i<len; i++) { if (!this[i]) {nullCount++} }
// no item is null
if (!nullCount) { return this}
// all items are null
if (nullCount == length) { this.length = 0; return this }
// mix of null // non-null
var idest=0, isrc=length-1;
length -= nullCount ;
while (true) {
// find a non null (source) slot on the right
while (!this[isrc]) { isrc--; nullCount--; }
if (!nullCount) { break } // break if found all null
// find one null slot on the left (destination)
while ( this[idest]) { idest++ }
// perform copy
this[idest]=this[isrc];
if (!(--nullCount)) {break}
idest++; isrc --;
}
this.length=length;
return this;
};
Object.defineProperty(Array.prototype, 'removeNull',
{ value : removeNull, writable : true, configurable : true } ) ;
arr.filter(e => e)
.
smart
- như là động từ, để gây ra một cơn đau nhói. Điều này có liên quan do nỗi đau thể xác nếu tôi vũ khí hóa điện thoại của tôi do nhận xét của bạn.
'Lạm dụng' vòng lặp for ... in (thành viên đối tượng). => Chỉ các giá trị trung thực xuất hiện trong phần thân của vòng lặp.
// --- Example ----------
var field = [];
field[0] = 'One';
field[1] = 1;
field[3] = true;
field[5] = 43.68;
field[7] = 'theLastElement';
// --- Example ----------
var originalLength;
// Store the length of the array.
originalLength = field.length;
for (var i in field) {
// Attach the truthy values upon the end of the array.
field.push(field[i]);
}
// Delete the original range within the array so that
// only the new elements are preserved.
field.splice(0, originalLength);
for ... in
là những gì loại bỏ các khóa không xác định khỏi mảng, nhưng thực tế bạn không có mã nào ở đây để chỉ chấp nhận các giá trị "trung thực"
Điều này có thể giúp bạn: https://lodash.com/docs/4.17.4#remove
var details = [
{
reference: 'ref-1',
description: 'desc-1',
price: 1
}, {
reference: '',
description: '',
price: ''
}, {
reference: 'ref-2',
description: 'desc-2',
price: 200
}, {
reference: 'ref-3',
description: 'desc-3',
price: 3
}, {
reference: '',
description: '',
price: ''
}
];
scope.removeEmptyDetails(details);
expect(details.length).toEqual(3);
scope.removeEmptyDetails = function(details){
_.remove(details, function(detail){
return (_.isEmpty(detail.reference) && _.isEmpty(detail.description) && _.isEmpty(detail.price));
});
};
var data= {
myAction: function(array){
return array.filter(function(el){
return (el !== (undefined || null || ''));
}).join(" ");
}
};
var string = data.myAction(["I", "am","", "working", "", "on","", "nodejs", "" ]);
console.log(string);
Đầu ra:
Tôi đang làm việc trên nodejs
Nó sẽ loại bỏ phần tử rỗng khỏi mảng và hiển thị phần tử khác.
Nếu một mảng chứa các Đối tượng, Mảng và Chuỗi trống cùng với các phần tử trống khác, chúng ta có thể xóa chúng bằng:
const arr = [ [], ['not', 'empty'], {}, { key: 'value' }, 0, 1, null, 2, "", "here", " ", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ]
let filtered = JSON.stringify(
arr.filter((obj) => {
return ![null, undefined, ''].includes(obj)
}).filter((el) => {
return typeof el != "object" || Object.keys(el).length > 0
})
)
console.log(JSON.parse(filtered))
Với ES6:
const arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]
let filtered = arr.filter((obj) => { return ![null, undefined].includes(obj) })
console.log(filtered)
Với Javascript đơn giản ->
var arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]
var filtered = arr.filter(function (obj) { return ![null, undefined].includes(obj) })
console.log(filtered)
Lọc các mục không hợp lệ bằng biểu thức chính quy
array = array.filter(/\w/);
filter + regexp
Cách tốt nhất để loại bỏ các yếu tố trống, là sử dụng Array.prototype.filter()
, như đã được đề cập trong các câu trả lời khác.
Thật không may, Array.prototype.filter()
không được IE <9 hỗ trợ. Nếu bạn vẫn cần hỗ trợ IE8 hoặc phiên bản IE cũ hơn, bạn có thể sử dụng polyfill sau để thêm hỗ trợ cho Array.prototype.filter()
các trình duyệt này:
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/*, thisArg*/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
var a = [,,]
vàvar a = [undefined, undefined]
. Cái trước thực sự trống rỗng, nhưng cái sau thực sự có hai khóa, nhưng cóundefined
giá trị.