ลบองค์ประกอบที่ว่างเปล่าออกจากอาร์เรย์ใน Javascript


1145

ฉันจะลบองค์ประกอบว่างออกจากอาร์เรย์ใน JavaScript ได้อย่างไร

มีวิธีที่ตรงไปตรงมาหรือฉันจำเป็นต้องวนซ้ำมันและลบออกด้วยตนเอง?


14
มันจะมีประโยชน์หากคำถามของคุณระบุสิ่งที่คุณหมายถึงโดย "องค์ประกอบที่ว่างเปล่า" เนื่องจากคำตอบส่วนใหญ่ที่นี่ตีความว่าไม่ถูกต้อง (IMHO) เพื่อหมายถึงองค์ประกอบ "เท็จ" หมายเหตุ: มีความแตกต่างระหว่างสิ่งที่คุณได้รับและvar a = [,,] var a = [undefined, undefined]อดีตนั้นว่างเปล่าจริง ๆ แต่อันที่จริงมีสองปุ่ม แต่มีundefinedค่า
Alnitak

คำตอบ:


1065

แก้ไข: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);

มันจะขึ้นอยู่กับสิ่งที่คุณคิดว่าเป็น "ว่างเปล่า" ตัวอย่างเช่นหากคุณกำลังจัดการกับสตริงฟังก์ชันข้างต้นจะไม่ลบองค์ประกอบที่เป็นสตริงว่าง

หนึ่งในรูปแบบทั่วไปที่ฉันมักจะเห็นใช้คือการเอาองค์ประกอบที่เป็นfalsyซึ่งรวมถึงสตริงที่ว่างเปล่า"", 0, NaN, null, และundefinedfalse

คุณสามารถส่งผ่านไปยังfilterเมธอดBooleanฟังก์ชันตัวสร้างหรือส่งคืนองค์ประกอบเดียวกันในฟังก์ชันตัวกรองเกณฑ์ตัวอย่างเช่น:

var filtered = array.filter(Boolean);

หรือ

var filtered = array.filter(function(el) { return el; });

ในรูปแบบที่ทั้งสองงานนี้เพราะfilterวิธีการในกรณีแรกเรียกBooleanตัวสร้างเป็นฟังก์ชั่นการแปลงค่าและในกรณีที่สองวิธีการเปลี่ยนภายในค่าตอบแทนของการเรียกกลับไปโดยปริยายfilterBoolean

หากคุณกำลังทำงานกับกระจัดกระจายอาร์เรย์และคุณพยายามที่จะกำจัด "หลุม" คุณสามารถใช้filterวิธีการผ่านการเรียกกลับที่ส่งกลับจริงตัวอย่างเช่น:

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,,,,]);

110
คำเตือน: ตัวเลือกที่ 2 จะลบองค์ประกอบใด ๆ ออกจากอาร์เรย์ที่พิจารณาว่า "เท็จ" เช่นค่าเท็จ, 0, null และไม่ได้กำหนด อาร์เรย์นี้จะลงท้ายด้วยไม่มีอะไรเลยในนั้น: [null ,,, 0,, ​​0,0,0, false, null, 0] แม้ว่าฉันอาจต้องการองค์ประกอบที่มีค่า 0 เช่นเดียวกับในอาร์เรย์นี้: [ 1,0,1,0,0,1]
Jason Bunting

5
ฉันรู้ว่า - ซึ่งเป็นเหตุผลที่ฉันพูดถึงตัวเลือกที่สองเท่านั้น สำหรับอันแรกมันแคบมากจนฉันลังเลที่จะทำให้มันเป็นส่วนหนึ่งของต้นแบบของอาเรย์ ดูคำตอบของ Alnitak ในหน้านี้สำหรับบางสิ่งที่เหมาะกว่า คุณยอมให้ผูกมัดอย่างชัดเจน
35490 Jason

1
วิธีแก้ปัญหาแรกของคุณดีมากถ้าคุณไม่สามารถเข้าถึงวิธี "ตัวกรอง" อื่นฉันเชื่อว่าคำตอบของ Alnitak ดีกว่า
Joe Pineda

2
@AlfaTek - นอกเหนือจากเบราว์เซอร์ใหม่ล่าสุด # 2 จะมีประสิทธิภาพที่ดีที่สุดเพราะอาร์เรย์ใน JS ไม่ใช่อาร์เรย์จริงๆ การspliceโทรนั้นมีราคาแพงมากในเบราว์เซอร์รุ่นเก่าเนื่องจากต้องทำการกำหนดหมายเลขคีย์อาร์เรย์ทั้งหมดใหม่เพื่อปิดช่องว่าง
Alnitak

1
@David no ในรหัสที่ทันสมัยคุณควรขยายการใช้งานอย่างปลอดภัยเพื่อทำให้ฟังก์ชั่นใหม่เป็นคุณสมบัติที่ไม่นับจำนวนและหลีกเลี่ยงการตีประสิทธิภาพที่เกิดจากการใส่ทุกลูป Array.prototypeObject.defineProperty.hasOwnProperty
Alnitak

1381

วิธีง่าย ๆ :

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]

หรือ - (สำหรับไอเท็มอาเรย์เดี่ยวประเภท "text" เท่านั้น)

['','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;

arr // [1, 2, 3, 3, 4, 4, 5, 6]

ลบค่าว่าง

['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]

34
การสนับสนุน IE ที่เร็วที่สุดสำหรับตัวกรองคือโหมดมาตรฐาน IE9
yincrash

14
สำหรับจาวาสคริปต์ที่บริสุทธิ์ควรเป็นarr = arr.filter(function(n){return n; });
ilumin

19
foo.join("").split("")ดูเหมือนว่าจะใช้งานได้หากสตริงเป็นอักขระเดียว
Atav32

9
รหัส JavaScript บริสุทธิ์ของคุณมีข้อบกพร่อง หากอาร์เรย์มีค่าที่มี "0" อยู่ในนั้นค่าจะถูกกรองออกเพราะ "0" เป็นเท็จ สิ่งที่คุณต้องการคือ: arr.filter (ฟังก์ชั่น (n) {return (n! == undefined && n! == null);});
John Kurlak

5
ES6 สามารถทำได้ง่ายขึ้นarr.filter(e=>e)และสิ่งนี้สามารถถูกล่ามโซ่โดยแผนที่ลดและอื่น ๆ
Sheepy

241

หากคุณต้องการลบค่าว่างเปล่าทั้งหมด ("", โมฆะ, ไม่ได้กำหนดและ 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, " "]

อัปเดต (ขึ้นอยู่กับความคิดเห็นของ Alnitak)

ในบางสถานการณ์คุณอาจต้องการให้ "0" อยู่ในอาร์เรย์และลบสิ่งอื่นใด (โมฆะไม่ได้กำหนดและ "") นี่เป็นวิธีหนึ่ง:

arr.filter(function(e){ return e === 0 || e });

กลับ:

["hello", 0, 1, 100, " "]

ใช่นี่คือ cuz ที่ดีจะลบ "" เช่นกัน
วลาดีมี

3
ฟังก์ชั่นทดสอบอาจชัดเจนกว่านี้เล็กน้อย:function(e){return !!e}
Koen

4
@Koen โปรดทราบว่า!!eจะมี NaN (ไม่เหมือน 0) โดยที่eจะไม่ (เช่น 0)
Sheepy

ไม่ตอบคำถามที่ถามจริง
Alnitak

2
หรือใช้var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);ลบออกไม่ได้กำหนด "" และ 0
Mark Schultheiss

134

เพียงหนึ่งซับ:

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

1
นี่มันเจ๋งจริงๆ - ฉันมีคำถามใหม่ ๆ : ดูเหมือนว่าคุณกำลังใช้ชื่อคลาสเป็นฟังก์ชันการโทร - นั่นเป็น typecasting หรือไม่ ฉันไม่ได้เห็นนี้มาก่อนและผมไม่แน่ใจว่าผมได้รับเหตุผลที่ผ่านBooleanผลงานที่เป็นฟังก์ชั่น ...
แอนดรู

8
หากคุณปฏิบัติต่อBooleanฟังก์ชั่นมันก็จะคืนค่าtrueหรือfalseเป็นค่าที่แท้จริง / เท็จ
andlrc

8
คุณไม่ได้ถือว่าบูลีนเป็นฟังก์ชัน มันเป็นฟังก์ชั่น (ฟังก์ชั่นปกติอย่างสมบูรณ์ยกเว้นว่ามันถูกนำมาใช้โดยกำเนิด) ใครบางคนต้องทำการวิจัยเล็กน้อยเกี่ยวกับรูปแบบวัตถุ JavaScript ;)
ELLIOTTCABLE

@ELLIOTTCABLE ฉันแค่จะออกจากที่นี่(true).constructor === Booleanแล้ว จากนั้นบอกฉันว่าเราสามารถทำสิ่งนี้กับบิลด์อื่นใน JS ได้ไหม ;)) (แน่นอนว่าไม่รวมตัวสร้างบิลด์อินอีก 5 ตัว (String, Array, Object, Function, Number))
andlrc

1
จะล้มเหลวทั้งสองถ้ามีค่า 0 ในอาร์เรย์
Sai Ram

129

หากคุณมี Javascript 1.6 หรือใหม่กว่าคุณสามารถใช้Array.filterโดยใช้return trueฟังก์ชันการโทรกลับเล็กน้อยเช่น:

arr = arr.filter(function() { return true; });

ตั้งแต่.filterข้ามองค์ประกอบที่หายไปโดยอัตโนมัติไปในอาร์เรย์เดิม

หน้า MDN ที่ลิงก์ด้านบนยังมีเวอร์ชันการตรวจสอบข้อผิดพลาดที่ดีfilterซึ่งสามารถใช้ในล่าม JavaScript ที่ไม่รองรับเวอร์ชันอย่างเป็นทางการ

โปรดทราบว่าสิ่งนี้จะไม่ลบnullรายการหรือรายการที่มีundefinedค่าชัดเจนแต่ OP ขอรายการ "หายไป" โดยเฉพาะ


คุณถูก! มันง่ายมากเช่นนี้ (และได้ผล!): test3 = [1,2,, 3,, 3 ,,,, 7 ,,, 7 ,,, 0 ,,, 4,, 4,, 5 ,, 6, undefined ,, null ,,]; printp ("การใช้การกรองเนทีฟของอาร์เรย์:", test3.filter (ฟังก์ชัน (ค่า) {return (value == undefined)? 0: 1;}));
Joe Pineda

3
+1 ดังที่ Alnitak กล่าวว่าพวกเขามีรหัสที่สามารถใช้ในกรณีที่ไม่มี js 1.6 ให้ใช้งานได้
Sameer Alibhai

3
@katsh ฉันชี้แจง - รหัสข้างต้นใช้งานได้เพื่อลบรายการที่ไม่มีค่าอยู่เลยซึ่ง (ฉันภายหลัง) เรียนรู้ว่ามีความหมายแตกต่างจากกรณีของคีย์ที่มีอยู่ แต่มีundefinedค่าที่กำหนด
Alnitak

4
หากต้องการลบรายการที่ไม่ได้กำหนดหรือเป็นโมฆะเพียงทำการเปลี่ยนแปลงเล็กน้อย ... arr = arr.filter (function (v) {return v;});
อลัน CN

4
@ AlanCN คุณพลาดจุดของฉันไปโดยสิ้นเชิง OP ขอให้ลบรายการที่หายไปในขณะที่คำตอบจำนวนมากที่นี่ (ไม่ถูกต้อง) ลบรายการ "falsey" ใด ๆ
Alnitak

65

สำหรับการลบรูคุณควรใช้

arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this

สำหรับการลบรูและค่าเท็จ (ค่า null ไม่ได้กำหนด 0, -0, NaN, "", false, document.all):

arr.filter(x => x)

สำหรับการลบหลุม null และไม่ได้กำหนด:

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]


3
นี่ควรจะสูงขึ้นในคำตอบ คุณช่วยขยายความหมายของหลุม / หลุม ..
samayo

2
@samayo หลุมเป็นรายการอาร์เรย์ที่ไม่สำเร็จเช่น[, ,]
Jimmy Obonyo Abor

โดยการใช้arr.filter(x => x)JS จะตรวจสอบว่า x เป็นจริงหรือเท็จเช่นif (x)ดังนั้นเฉพาะค่าความจริงจะถูกกำหนดให้กับรายการใหม่
KuanYu Chu

56

วิธีทำความสะอาดที่ทำได้

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

5
องค์ประกอบที่ว่างเปล่าคือundefined; สิ่งนี้จะลบค่าที่ผิดทั้งหมด
pimvdb

33

ES6 ง่าย ๆ

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

1
สิ่งนี้ใช้ไม่ได้: [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v).
ซิป

22

ด้วยขีดล่าง / 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 หาโดยไม่


ปัญหากับ #compact คือการลบค่าที่ผิดพลาดใด ๆ ดังนั้นถ้าอาร์เรย์ของคุณมีค่า 0 มันจะถูกลบออกด้วย
ซามูเอลBrandão

21

เพียงแค่ES6วิธีการรุ่นใหม่สมมติอาร์เรย์อยู่ด้านล่าง:

 const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];

วิธีง่าย ๆ :

 const clearArray = arr.filter( i => i );

16

หากใช้ห้องสมุดเป็นตัวเลือกฉันรู้ว่า underscore.js มีฟังก์ชันที่เรียกว่า compact () http://documentcloud.github.com/underscore/มันยังมีฟังก์ชั่นที่มีประโยชน์อื่น ๆ อีกมากมายที่เกี่ยวข้องกับอาร์เรย์และคอลเลกชัน

นี่คือข้อความที่ตัดตอนมาจากเอกสารของพวกเขา:

_.compact (อาร์เรย์)

ส่งคืนสำเนาของอาร์เรย์โดยลบค่าความเท็จทั้งหมด ใน JavaScript, false, null, 0, "", ไม่ได้กำหนดและ NaN ล้วนเป็นเท็จ

_.compact ([0, 1, เท็จ, 2, '', 3]);

=> [1, 2, 3]


นอกจากนี้ยังลบองค์ประกอบที่ไม่ได้กำหนดองค์ประกอบที่ว่างเช่น 0
Timothy Gu

15

@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 แต่ตัวกรองและการเขียนโปรแกรมฟังก์ชั่นที่คุ้มค่าคือ imo

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

นี่ควรเป็นคำตอบที่ได้รับการยอมรับเนื่องจากใช้งานได้ดี ขอบคุณมาก ๆ.
โทนี่

@ โทนี่ไม่ควรเพราะองค์ประกอบที่มีสตริงว่างในนั้นไม่เหมือนกับ "องค์ประกอบว่าง" ซึ่งเป็นสิ่งที่ OP ต้องการ
Alnitak

14

_.without(array, *values);เนื่องจากไม่มีใครพูดถึงเรื่องนี้และคนส่วนใหญ่ได้รวมขีดในโครงการของพวกเขาคุณยังสามารถใช้

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]


8

คุณอาจพบว่าการวนลูปมากกว่าอาเรย์ของคุณง่ายขึ้นและสร้างอาเรย์ใหม่ออกจากไอเท็มที่คุณต้องการเก็บจากอาเรย์มากกว่าโดยการลองวนซ้ำและการประกบกันตามที่ได้แนะนำไว้เนื่องจากการแก้ไขความยาวของอาเรย์ มากกว่าสามารถแนะนำปัญหา

คุณสามารถทำสิ่งนี้:

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]

คุณได้รับแนวคิด - จากนั้นคุณสามารถใช้ฟังก์ชันตัวกรองประเภทอื่น อาจมากกว่าที่คุณต้องการ แต่ฉันรู้สึกใจกว้าง ... ;)


7

สิ่งที่เกี่ยวกับเรื่องนี้ (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"]

6

คุณควรใช้ตัวกรองเพื่อรับอาร์เรย์โดยไม่มีองค์ประกอบว่างเปล่า ตัวอย่างบน ES6

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

3

ฉันเพียงแค่การเพิ่มเสียงของฉันข้างต้น“การเรียกร้อง ES5 ของArray..filter()ด้วยตัวสร้างโลก” กอล์ฟสับ แต่ฉันขอแนะนำให้ใช้ObjectแทนString, BooleanหรือNumberตามที่แนะนำข้างต้น

โดยเฉพาะ ES5 filter()นั้นไม่ได้เรียกใช้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 และทำให้ในการตั้งค่าบูลีนเป็นระยะสั้นมือสำหรับObjectfunction(){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
ระวัง: ตัวกรอง (สตริง) และตัวกรอง (วัตถุ) อย่ากรองค่าว่างหรือตัวเลข เนื่องจากนวกรรมิกยังเป็นฟังก์ชั่นที่คุณสามารถส่งผ่าน String ไปยังตัวกรองนั่นsomeArray.filter(String);คือเทียบเท่าจริงsomeArray.filter(function(x){ return String(x); });ๆ หากคุณต้องการลบค่าที่เป็นเท็จทั้งหมดsomeArray.filter(Boolean);จะทำการลบ 0, -0, NaN, false, '', null และ undefined
robocat

1
คำตอบที่ดีแม้ว่าฉันจะสงสัยเกี่ยวกับค่าใช้จ่ายในการเรียกคอนObjectสตรัคเตอร์เมื่อเทียบกับreturn trueวิธีการ @robocat OP ขอให้ลบองค์ประกอบที่ว่างเปล่าไม่ใช่โมฆะ
Alnitak

ฉันชอบทางออกที่สั้นที่สุดและชัดเจนที่สุดยกเว้นในวงแคบ การตั้งค่าส่วนตัวฉันคิดว่า (=
ELLIOTTCABLE

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

+1 เนื่องจากเป็นจริงมากและสิ่งที่ฉันมักจะต้องทำงานกับอาร์เรย์สตริง แต่ทราบว่านี้ลบตัวเลข (ถ้าพวกเขาไม่ได้อยู่ในรูปแบบสตริง) เนื่องจากพวกเขาไม่มี. ความยาวดังนั้น["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123แทนที่ฟังก์ชันนั้น .. ด้วย String แดกดันทิ้งตัวเลขไว้ แต่จะให้ผลลัพธ์แบบเดียวกันกับอาร์เรย์ที่คุณระบุ
aamarks

3
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]


นี่เป็นวิธีที่ถูกต้องอย่างชัดเจนที่จะทำและควรจะอยู่ด้านบน!
Martin Andersson


1

ใช้งานได้แล้วฉันทดสอบใน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]
*/

1
สิ่งนี้ดูเหมือนจะใช้งานได้ "โดยไม่ได้ตั้งใจ" เท่านั้นเนื่องจากเป็นหน้าที่ของการแจกแจงคีย์ผ่านทางfor ... inที่เป็นสาเหตุของการข้ามองค์ประกอบที่ขาดหายไป การทดสอบundefinedทำหน้าที่เพียงลบองค์ประกอบจริงที่กำหนดไว้อย่างชัดเจนเป็นค่านั้น
Alnitak

1

อีกวิธีในการทำคือใช้ประโยชน์จากคุณสมบัติความยาวของอาเรย์: แพ็คไอเท็มที่ไม่เป็นโมฆะใน 'ซ้าย' ของอาเรย์แล้วลดความยาว มันเป็นอัลกอริธึมในสถานที่ - ไม่ได้จัดสรรหน่วยความจำแย่เกินไปสำหรับตัวรวบรวมขยะ - และมีลักษณะการทำงานของเคสที่ดีที่สุด / โดยเฉลี่ย / แย่ที่สุด

โซลูชันนี้เปรียบเทียบกับคนอื่น ๆ ที่นี่ได้เร็วกว่า Chrome อยู่ระหว่าง 2 ถึง 50 เท่าและเร็วกว่า Firefox 5 ถึง 50 เท่าดังที่คุณเห็นที่นี่: http://jsperf.com/remove-null-items-from-array

โค้ดด้านล่างเพิ่มวิธี 'removeNull' ที่ไม่สามารถนับได้ไปยัง Array ซึ่งส่งคืน '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 } ) ;

คำตอบที่ดีแม้ว่ามันจะเป็นการดีที่ได้เห็นบางกรณีทดสอบเพื่อแสดงมันในการดำเนินการ!
Alnitak

2
คำตอบนี้เป็นที่น่าสนใจมาก แต่ชนิดของผมนึกถึงมองที่เครื่องคอมพิวเตอร์ที่สร้างขึ้นในปี 1945 arr.filter(e => e)เมื่อฉันมีมาร์ทโฟน:
agm1984

@ agm1984 สมาร์ทโฟนของคุณไม่ได้ฉลาด
Hernán Eche

นั่นอาจขึ้นอยู่กับคำจำกัดความของคุณ - smartเช่นคำกริยาเพื่อทำให้เกิดอาการปวดแสบที่คมชัด สิ่งนี้มีความเกี่ยวข้องเนื่องจากความเจ็บปวดทางกายภาพหากฉันติดอาวุธในโทรศัพท์ของฉันเนื่องจากความคิดเห็นของคุณ
agm1984

1
foo = [0, 1, 2, "", , false, 3, "four", null]

foo.filter(function(e) {
    return e === 0 ? '0' : e
})

ผลตอบแทน

[0, 1, 2, 3, "four"]

1

'การใช้ผิด' การ for ... in (สมาชิกวัตถุ) => เฉพาะค่าความจริงเท่านั้นที่ปรากฏในเนื้อความของลูป

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

รหัสถูกต้องความคิดเห็นนั้นผิด การกระทำของการใช้for ... inคือสิ่งที่ลบคีย์ที่ไม่ได้กำหนดออกจากอาร์เรย์ แต่จริงๆแล้วคุณไม่มีรหัสที่นี่เพื่อรับค่า "ความจริง" เท่านั้น
Alnitak

1

สิ่งนี้อาจช่วยคุณได้: https://lodash.com/docs/4.17.4#remove

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));
            });
        };

1
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

มันจะลบองค์ประกอบที่ว่างเปล่าจากอาร์เรย์และแสดงองค์ประกอบอื่น ๆ


เอาต์พุต: 'ฉันกำลังทำงานกับ nodejs' มันจะลบองค์ประกอบที่ว่างเปล่าจากอาร์เรย์และแสดงองค์ประกอบอื่น ๆ
Jitendra virani

ฉันปรับปรุงคำตอบของคุณ โปรดลองทำคำตอบที่ง่ายชัดเจนและอ่านได้)
GGO

1

การลบองค์ประกอบที่ว่างเปล่าทั้งหมด

หากอาร์เรย์มีวัตถุที่ว่างเปล่าอาร์เรย์และสตริงข้างองค์ประกอบที่ว่างเปล่าอื่น ๆ เราสามารถลบออกได้ด้วย:

const arr = [ [], ['not', 'empty'], {}, { key: 'value' }, 0, 1, null, 2, "", "here", " ", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ]

let filtered = JSON.stringify(
  arr.filter((obj) => {
    return ![null, undefined, ''].includes(obj)
  }).filter((el) => {
    return typeof el != "object" || Object.keys(el).length > 0
  })
)

console.log(JSON.parse(filtered))

การย่อขนาดง่าย ๆ (ลบองค์ประกอบที่ว่างเปล่าออกจากอาร์เรย์)

ด้วย ES6:

const arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

let filtered = arr.filter((obj) => { return ![null, undefined].includes(obj) })

console.log(filtered)

ด้วย Javascript ธรรมดา ->

var arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

var filtered = arr.filter(function (obj) { return ![null, undefined].includes(obj) })

console.log(filtered)


0

กรองรายการที่ไม่ถูกต้องด้วยนิพจน์ทั่วไป

array = array.filter(/\w/);
filter + regexp

มันใช้ได้ไหม? มันแสดงให้เห็นข้อผิดพลาดTypeError: [วัตถุ RegExp] ไม่ใช่ฟังก์ชั่น
FreeLightman

0

วิธีที่ดีที่สุดในการลบองค์ประกอบที่ว่างเปล่าคือการใช้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;
  };
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.