سؤال

كيف أقوم بإزالة العناصر الفارغة من مصفوفة في 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]

underscorejs.org :

_.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 هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top