إزالة العناصر الفارغة من مصفوفة في Javascript
-
07-07-2019 - |
سؤال
كيف أقوم بإزالة العناصر الفارغة من مصفوفة في JavaScript؟
هل هناك طريقة مباشرة أم أحتاج إلى تكرارها وإزالتها يدويًا؟
المحلول
يحرر: تمت الإجابة على هذا السؤال منذ 9 سنوات تقريبًا، عندما لم يكن هناك الكثير من الأساليب المدمجة المفيدة في Array.prototype
.
الآن، بالتأكيد أود أن أوصيك باستخدام filter
طريقة.
ضع في اعتبارك أن هذه الطريقة ستعيدك مجموعة جديدة مع العناصر التي تمرر معايير وظيفة رد الاتصال التي تقدمها لها، على سبيل المثال، إذا كنت تريد الإزالة null
أو undefined
قيم:
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);
سيعتمد الأمر على ما تعتبره "فارغًا"، على سبيل المثال، إذا كنت تتعامل مع سلاسل، فلن تقوم الوظيفة المذكورة أعلاه بإزالة العناصر التي تمثل سلسلة فارغة.
أحد الأنماط الشائعة التي أرى استخدامها كثيرًا هو إزالة العناصر الموجودة كاذبة, ، والتي تتضمن سلسلة فارغة ""
, 0
, NaN
, null
, undefined
, ، و false
.
يمكنك ببساطة المرور إلى filter
الطريقة، Boolean
وظيفة المنشئ، أو ببساطة إرجاع نفس العنصر في وظيفة معايير التصفية، على سبيل المثال:
var filtered = array.filter(Boolean);
أو
var filtered = array.filter(function(el) { return el; });
يعمل هذا في كلا الاتجاهين لأن filter
الأسلوب في الحالة الأولى، يستدعي Boolean
منشئ كدالة، وتحويل القيمة، وفي الحالة الثانية، filter
تقوم الطريقة داخليًا بتحويل القيمة المرجعة لرد الاتصال ضمنيًا إلى Boolean
.
إذا كنت تعمل باستخدام صفائف متفرقة، وتحاول التخلص من "الثقوب"، فيمكنك ببساطة استخدام الأمر filter
طريقة لتمرير رد اتصال يُرجع صحيحًا، على سبيل المثال:
var sparseArray = [0, , , 1, , , , , 2, , , , 3],
cleanArray = sparseArray.filter(function () { return true });
console.log(cleanArray); // [ 0, 1, 2, 3 ]
الجواب القديم: لا تفعل هذا!
أستخدم هذه الطريقة لتوسيع النموذج الأولي للصفيف الأصلي:
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);
أو يمكنك ببساطة دفع العناصر الموجودة إلى مصفوفة أخرى:
// 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,,,,]);
نصائح أخرى
طرق بسيطة:
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]
أو - (فقط ل أعزب عناصر المصفوفة من النوع "نص")
['','1','2',3,,'4',,undefined,,,'5'].join('').split('');
// output: ["1","2","3","4","5"]
أو - الطريقة الكلاسيكية:تكرار بسيط
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]
تحديث - طريقة أخرى سريعة ورائعة (باستخدام ES6):
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;
delete temp; // discard the variable
arr // [1, 2, 3, 3, 4, 4, 5, 6]
إزالة القيم الفارغة
['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)
// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
إذا كنت بحاجة إلى إزالة كافة القيم الفارغة (""، فارغة، غير محددة و0):
arr = arr.filter(function(e){return e});
لإزالة القيم الفارغة وفواصل الأسطر:
arr = arr.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});
مثال:
arr = ["hello",0,"",null,undefined,1,100," "]
arr.filter(function(e){return e});
يعود:
["hello", 1, 100, " "]
تحديث (بناءً على تعليق النطاق)
في بعض المواقف قد ترغب في الاحتفاظ بالرقم "0" في المصفوفة وإزالة أي شيء آخر (خالي وغير محدد و"")، وهذه إحدى الطرق:
arr.filter(function(e){ return e === 0 || e });
يعود:
["hello", 0, 1, 100, " "]
ومجرد واحدة بطانة:
[1, false, "", undefined, 2].filter(Boolean); // [1, 2]
_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
إذا كان لديك Javascript 1.6 أو إصدار أحدث، فيمكنك استخدامه Array.filter
باستخدام تافهة return true
وظيفة رد الاتصال، على سبيل المثال:
arr = arr.filter(function() { return true; });
منذ .filter
يتخطى تلقائيًا العناصر المفقودة في المصفوفة الأصلية.
تحتوي صفحة MDN المرتبطة أعلاه أيضًا على إصدار جيد للتحقق من الأخطاء filter
التي يمكن استخدامها في مترجمات JavaScript التي لا تدعم الإصدار الرسمي.
لاحظ أن هذا لن يزيل null
إدخالات ولا إدخالات مع صريحة undefined
القيمة، لكن OP طلب على وجه التحديد الإدخالات "المفقودة".
لإزالة الثقوب، يجب عليك استخدام
arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this
لإزالة حفرة، و، falsy (خالية، غير معروف، 0، -0، نان، ""، كاذبة، document.all) القيم:
arr.filter(x => x)
لإزالة حفرة، لاغية، وغير معروف:
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]
والطريقة نظيفة للقيام بذلك.
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"]
وبسيط ES6
['a','b','',,,'w','b'].filter(v => v);
مع الشرطة السفلية/Lodash:
حالة الاستخدام العام:
_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
مع الفراغات:
_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]
يرى وثائق lodash بدون.
وفقط ES6
وأحدث طريقة الإصدارات، تفترض مجموعة هو التالي:
const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];
وطريقة بسيطة:
const clearArray = arr.filter( i => i );
إذا باستخدام مكتبة هو خيار أعرف underscore.js لديه وظيفة ودعا الميثاق () HTTP: // documentcloud.github.com/underscore/ كما أن لديها عدة وظائف مفيدة أخرى تتعلق المصفوفات والمجموعات.
وهنا مقتطف من وثائقهم:
<اقتباس فقرة>و_. المدمجة (مجموعة)
وإرجاع نسخة من مجموعة مع كل القيم falsy إزالتها. في جافا سكريبت، كاذبة، لاغية، 0، ""، غير معروف ونان كلها falsy.
و_ المدمجة ([0، 1، كاذبة، 2، ''، 3])؛.
و=> [1، 2، 3]
اقتباس فقرة>وAlnitak
والواقع Array.filter يعمل على جميع المتصفحات إذا قمت بإضافة بعض رمز إضافية. انظر أدناه.
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"]
وهذا هو رمز تحتاج إلى إضافة لIE، ولكن تصفية وظيفية قيمتها programmingis غير المنظمة البحرية الدولية.
//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;
};
}
ومنذ لا أحد آخر ذكر أنه ومعظم الناس قد شملت تسطير في مشروعهم يمكنك أيضا استخدام _.without(array, *values);
.
_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
وأنت قد تجد أنه من الأسهل لحلقة على مجموعة الخاصة بك وبناء مجموعة جديدة من العناصر التي تريد أن تبقي من مجموعة من خلال محاولة حلقة ولصق كما اقترح، منذ تعديل طول المصفوفة في حين أنه ويجري يحلق فوق يمكن أن يعرض المشاكل.
هل يمكن أن تفعل شيئا من هذا القبيل:
function removeFalsyElementsFromArray(someArray) {
var newArray = [];
for(var index = 0; index < someArray.length; index++) {
if(someArray[index]) {
newArray.push(someArray[index]);
}
}
return newArray;
}
والواقع هنا هو حل أكثر عمومية:
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]
ويمكنك الحصول على فكرة - هل يمكن بعد ذلك أنواع أخرى من وظائف التصفية. أكثر ربما مما تحتاج، ولكن كنت أشعر سخي ...؛)
ES6: let newArr = arr.filter(e => e);
ماذا عن هذا (ES6):لإزالة القيمة الزائفة من صفيف.
var arr = [0,1,2,"test","false",false,true,null,3,4,undefined,5,"end"];
arr.filter((v) => (!!(v)==true));
//output:
//[1, 2, "test", "false", true, 3, 4, 5, "end"]
ويجب عليك استخدام فلتر للحصول على مجموعة بدون عناصر فارغة. مثال على ES6
const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
وأنا ببساطة بضم صوتي إلى ما سبق "دعوة Array..filter()
ES5 مع منشئ العالمي" للجولف من الإختراق، ولكن أقترح استخدام Object
بدلا من String
، Boolean
، أو Number
على النحو المقترح أعلاه.
وعلى وجه التحديد، filter()
ES5 بالفعل لا يؤدي لعناصر undefined
ضمن مجموعة. لذلك دالة تقوم بإرجاع عالميا true
، والتي ترجع <م> جميع م> عناصر filter()
الزيارات، سوف بالضرورة فقط العودة العناصر غير undefined
:
> [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]
ولكن، والكتابة خارج ...(function(){return true;})
أطول من كتابة ...(Object)
. والقيمة عودة منشئ Object
ستكون تحت أي ظرف من الظروف م>، نوعا من الكائنات. وخلافا لل-الملاكمة-الصانعين البدائية المقترحة أعلاه، لا قيمة الكائن الممكنة هي falsey، وبالتالي في إعداد منطقية، Object
هو اليد قصيرة ل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]
عند استخدام الإجابة الأعلى تصويتًا أعلاه، المثال الأول، كنت أحصل على أحرف فردية لأطوال سلسلة أكبر من 1.أدناه هو الحل الخاص بي لهذه المشكلة.
var stringObject = ["", "some string yay", "", "", "Other string yay"];
stringObject = stringObject.filter(function(n){ return n.length > 0});
بدلاً من عدم العودة إذا كان غير محدد، نعود إذا كان الطول أكبر من 0.نأمل أن يساعد شخص ما هناك.
عائدات
["some string yay", "Other string yay"]
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r)
<اقتباس فقرة>
[1،2،3]
اقتباس فقرة>وماذا عن ما يلي:
js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
وهذا يعمل، اختبرته في AppJet (يمكنك نسخ ولصق رمز على IDE والصحافة " تحميل "لمعرفة ما يعمل، لا تحتاج إلى إنشاء حساب)
/* 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]
*/
هناك طريقة أخرى للقيام بذلك وهي الاستفادة من خاصية length للمصفوفة:قم بحزم العناصر غير الخالية على "يسار" المصفوفة، ثم قم بتقليل الطول.إنها خوارزمية موضعية - لا تخصص الذاكرة، وهي سيئة للغاية بالنسبة لجامع البيانات المهملة - ولها سلوك جيد جدًا في أفضل/متوسط/أسوأ حالة.
هذا الحل، مقارنة بالحلول الأخرى هنا، أسرع بما يتراوح بين 2 إلى 50 مرة على Chrome، وأسرع من 5 إلى 50 مرة على Firefox، كما قد ترى هنا: http://jsperf.com/remove-null-items-from-array
يضيف التعليمة البرمجية أدناه طريقة "removeNull" غير القابلة للتعداد إلى المصفوفة، والتي تُرجع "هذا" للتسلسل التعاقبي:
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 } ) ;
foo = [0, 1, 2, "", , false, 3, "four", null]
foo.filter(function(e) {
return e === 0 ? '0' : e
})
عائدات
[0, 1, 2, 3, "four"]
'العبث' في ل... في (كائن عضوا) حلقة. => تظهر فقط القيم truthy في الجسم من الحلقة.
// --- 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);
وهذا قد تساعدك: https://lodash.com/docs/4.17.4# إزالة
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);
وإخراج:
<اقتباس فقرة>وأنا أعمل على nodejs
اقتباس فقرة>ووسوف إزالة عنصر فارغ من مجموعة وعرض عنصر آخر.
وتصفية خارج قيود غير صحيحة مع تعبير عادي
array = array.filter(/\w/);
filter + regexp
أفضل طريقة لإزالة العناصر الفارغة هي استخدامها Array.prototype.filter()
, ، كما سبق ذكره في الإجابات الأخرى.
للأسف، Array.prototype.filter()
غير مدعوم من IE<9.إذا كنت لا تزال بحاجة إلى دعم IE8 أو إصدار أقدم من IE، فيمكنك استخدام ما يلي polyfill لإضافة الدعم ل Array.prototype.filter()
في هذه المتصفحات:
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 qwerty = {
test1: null,
test2: 'somestring',
test3: 3,
test4: {},
test5: {
foo: "bar"
},
test6: "",
test7: undefined,
test8: " ",
test9: true,
test10: [],
test11: ["77","88"],
test12: {
foo: "foo",
bar: {
foo: "q",
bar: {
foo:4,
bar:{}
}
},
bob: {}
}
}
var asdfg = [,,"", " ", "yyyy", 78, null, undefined,true, {}, {x:6}, [], [2,3,5]];
function clean_data(obj) {
for (var key in obj) {
// Delete null, undefined, "", " "
if (obj[key] === null || obj[key] === undefined || obj[key] === "" || obj[key] === " ") {
delete obj[key];
}
// Delete empty object
// Note : typeof Array is also object
if (typeof obj[key] === 'object' && Object.keys(obj[key]).length <= 0) {
delete obj[key];
}
// If non empty object call function again
if(typeof obj[key] === 'object'){
clean_data(obj[key]);
}
}
return obj;
}
var objData = clean_data(qwerty);
console.log(objData);
var arrayData = clean_data(asdfg);
console.log(arrayData);
انتاج:
يزيل أي شيء null
, undefined
, ""
, " "
, empty object
أو empty array
com.jsfiddle هنا