Вопрос

Как удалить пустые элементы из массива в 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 метод, передающий обратный вызов, который возвращает true, например:

var sparseArray = [0, , , 1, , , , , 2, , , , 3],
    cleanArray = sparseArray.filter(function () { return true });

console.log(cleanArray); // [ 0, 1, 2, 3 ]

Старый ответ: Не делай этого!

Я использую этот метод, расширяя собственный прототип Array:

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]


через jQuery:

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, ()=>{}]

Если вам нужно удалить ВСЕ пустые значения ("", null, 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

Для удаления дырок и значений false (null, undefined, 0, -0, NaN, "", false, 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"]

Simple ES6

['a','b','',,,'w','b'].filter(v => v);

С Underscore / 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 есть функция Compact(). http://documentcloud.github.com/underscore/ он также имеет несколько других полезных функций, связанных с массивами и коллекциями.

Вот выдержка из их документации:

_.compact(массив)

Возвращает копию массива, из которой удалены все ложные значения.В JavaScript false, null, 0, "", undefine и NaN являются ложными.

_.compact([0, 1, ложь, 2, '', 3]);

=> [1, 2, 3]

@Альнитак

На самом деле 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, но фильтр и функциональное программирование, по моему мнению, того стоят.

//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(["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): удалить значение Falsy из массива.

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"]

Вы должны использовать фильтр, чтобы получить & nbsp; массив без пустых элементов. Пример на ES6

const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);

Я просто добавляю свой голос к вышеупомянутому & # 8220; вызову в ES5 Array..filter () с глобальным конструктором & # 8221; игра в гольф, но я предлагаю использовать Object вместо String , Boolean или Number , как предложено выше.

В частности, ES5 filter () уже не запускается для элементов undefined в массиве; поэтому функция, которая универсально возвращает true , которая возвращает все элементы filter () , обязательно вернет только не undefined elements:

> [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 при любых обстоятельствах будет чем-то вроде объекта. В отличие от конструкторов-примитивов, предложенных выше, ни одно из возможных значений-объектов не является ложным, и поэтому в логическом значении 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 массива: упаковать ненулевые элементы в «левую» часть массива, а затем уменьшить длину. Это алгоритм на месте - он не выделяет память, что очень плохо для сборщика мусора, и он очень хорошо работает в наилучшем / среднем / худшем случаях.

Это решение, по сравнению с другими, здесь, в Chrome, в 2–50 раз быстрее, а в Firefox - в 5–50 раз, как вы можете видеть здесь: http://jsperf.com/remove-null-items-from-array

Приведенный ниже код добавляет неперечислимый метод 'removeNull' в массив, который возвращает 'this' для последовательного подключения:

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"]

'Неправильное использование' цикла for ... in (object-member).   = & GT; В теле цикла отображаются только истинные значения.

// --- 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

jsfiddle здесь

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top