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