Как удалить пустые элементы из массива в JavaScript?
Есть ли прямой способ, или мне нужно пройтись по массиву и удалить их вручную?
<Н2>простые способы:</Н2>
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]
<БР/> <Н2>через jQuery:</Н2>
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]
<БР/> <Н2 и gt;Обновление - просто еще один быстрый, холодный способ (используя ES6 в):</Н2>
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, ()=>{}]
EDIT: Ответ на этот вопрос был дан почти девять лет назад, когда в 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,,,,]);
Если вам нужно удалить все пустые значения (" не наша" нулевой, неопределенный и 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" в массиве и удалить все остальное (значение null, неопределено и " Наша"), это один из способов:
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]
Если вы've получили в JavaScript 1.6 или более поздней версии вы можете использовать массив .фильтр
с помощью банального возвращения функция True` обратного вызова, например:
arr = arr.filter(function() { return true; });
с `.фильтр автоматически пропускает недостающих элементов в исходном массиве.
На странице МДН связано выше, также содержится хорошая проверка версии "фильтр", который может быть использован в JavaScript переводчиков, что Дон'т поддерживать официальную версию.
Обратите внимание, что это не будет удалить нуль
записи, ни записи с явной "неопределенным" значением, но ОП специально попросил "не хватает" по записи.
Для удаления отверстий, вы должны использовать
arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this
Для удаления отверстие, и, ложь (нуль, неопределено, 0, -0, NaN, то " не то", Ложь, документ.все) значения:
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"]
Подчеркивания/Лодашь:
Общий случай использования:
_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
С тарой:
_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]
Если вы используете библиотеку вариант, я знаю underscore.js имеет функцию под названием Compact() http://documentcloud.github.com/underscore она также имеет несколько других полезных функций, связанных с массивами и коллекциями.
Вот выдержка из документации:
_.компактный(массив)
возвращает копию массива с все удалены значения ложь. В JavaScript, "ложь", null, 0, " не то", не определено и Нэн все ложь.
_.компактный([0, 1, ложь, 2, '', 3]);
=> [1, 2, 3]
@Альнитак
На Самом Деле Массив.фильтр работает на всех браузерах, если вы добавить некоторые дополнительные код. См. ниже.
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(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
ES6: let newArr = arr.filter(e => e);
Возможно, вам будет проще зациклить массив и создать новый массив из элементов, которые вы хотите сохранить, чем пытаться зациклить и склеить, как было предложено, поскольку изменение длины массива во время его зацикливания может вызвать проблемы.
Вы можете сделать что-то вроде этого:
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]
Вы поняли идею - вы могли бы иметь другие типы функций фильтра. Возможно, это больше, чем вам нужно, но я чувствовал себя щедрым... ;)
Что по этому поводу(ЕС6) : удалить значение ложь из массива.
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"]
Вы должны использовать фильтр, чтобы получить массив без пустых элементов. Пример на ЕС6
const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
Я'м просто добавив свой голос к вышесказанному “звонок в ES5'ы массив..фильтр()
с глобальной конструктор” гольф-хак, но я предлагаю использовать объект
вместо строка
, логическое
или число
, как предложено выше.
В частности, в ES5'ы фильтр () уже не'т триггер на
неопределенныйэлементов в массиве; поэтому функция постоянно возвращает
true, который возвращает все элементы фильтра()
хитов, обязательно только для "неопределенным" элементы:
> [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]
Однако, выписывая ...(функция(){возвращение истинного;})
больше, чем писать...(объект); и вернуть значение
объектконструктор, при *любых обстоятельствах*, какой-то объект. В отличие от примитивно-бокс-конструкторы предложили выше, не представляется возможным объектом-значением является falsey, и при этом в параметр типа boolean,
объект- это сокращение для
функция(){возвратите 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]