ลบรายการออกจากอาร์เรย์โดยใช้ UnderscoreJS


137

สมมติว่าฉันมีรหัสนี้

var arr = [{id: 1, ชื่อ: 'a'}, {id: 2, ชื่อ: 'b'}, {id: 3, ชื่อ: 'c'}];

และฉันต้องการลบรายการที่มี id = 3 จากอาร์เรย์ มีวิธีในการทำเช่นนี้โดยไม่ต้องประกบ? เอาอะไรมาใช้ขีดล่างหรืออะไรแบบนั้น

ขอบคุณ!


หากคุณไม่ต้องการสร้างอาร์เรย์ใหม่การต่อเชื่อมเป็นทางเลือกเดียว ฉันเดิมพันขีดล่างใช้เช่นกัน (ภายในถ้ามีวิธีการดังกล่าวอยู่)
เฟลิกซ์คลิง

6
เกิดอะไรขึ้นกับการต่อรอย
Šime Vidas

คุณได้ตรวจสอบการอ้างอิงของขีดล่าง?
Šime Vidas

เพียงแค่ใช้ JavaScript ธรรมดานี้เป็นซ้ำเอาวัตถุจาก array โดยสถานวัตถุ
เฟลิกซ์คลิง

5
ไม่เหมือนกันเนื่องจากมีแท็กสำหรับ underscore.js
Garis M Suero

คำตอบ:


279

เพียงแค่ใช้ JavaScript ธรรมดานี้ได้รับการตอบแล้ว: เอาวัตถุจาก array โดยสถานวัตถุ

ใช้ underscore.js คุณสามารถรวม.findWhereกับ.without:

var arr = [{
  id: 1,
  name: 'a'
}, {
  id: 2,
  name: 'b'
}, {
  id: 3,
  name: 'c'
}];

//substract third
arr = _.without(arr, _.findWhere(arr, {
  id: 3
}));
console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

แม้ว่าในขณะที่คุณกำลังสร้างอาร์เรย์ใหม่ในกรณีนี้คุณสามารถใช้_.filterหรือArray.prototype.filterฟังก์ชันดั้งเดิม(เช่นเดียวกับที่แสดงในคำถามอื่น ๆ ) จากนั้นคุณจะวนซ้ำอาร์เรย์หนึ่งครั้งแทนที่จะเป็นสองเท่าที่นี่

หากคุณต้องการที่จะปรับเปลี่ยนอาร์เรย์ในสถานที่.spliceที่คุณต้องใช้ นี่ก็แสดงให้เห็นในคำถามอื่น ๆ และดูเหมือนว่า undescore จะไม่มีฟังก์ชันที่มีประโยชน์สำหรับสิ่งนั้น


1
ใช่มันทำงานได้อย่างสมบูรณ์แบบฉันได้อ่านเอกสารที่ขีดเส้นใต้แล้ว แต่ก็ไม่เข้าใจว่าจะดึงออกมาได้อย่างไร ขอบคุณ!
climboid

10
จะไม่ _.reject หรือ _.filter () มีประสิทธิภาพมากขึ้นที่นี่หรือไม่ คุณจะต้องทำซ้ำสองรายการเพื่อดึงรายการหนึ่งออกมา
Rick Strahl

1
นี่อาจจะซ้ำกัน แต่นี่เป็นคำตอบที่ดีกว่า
Michael J. Calkins

2
@RickStrahl คุณพูดถูก _.rejectดูเหมือนตัวเลือกที่ดีกว่าที่นี่
Tarik

1
@lukaserat เติมองค์ประกอบสุดท้ายใช้arr.pop()...
Emile Bergeron

96

คุณสามารถใช้ขีดล่าง .filter

    var arr = [{
      id: 1,
      name: 'a'
    }, {
      id: 2,
      name: 'b'
    }, {
      id: 3,
      name: 'c'
    }];

    var filtered = _(arr).filter(function(item) {
         return item.id !== 3
    });

สามารถเขียนเป็น:

var filtered = arr.filter(function(item) {
    return item.id !== 3
});

var filtered = _.filter(arr, function(item) {
    return item.id !== 3
});

ตรวจสอบซอ

คุณยังสามารถใช้ .reject


ฉันคิดว่าคุณหมายถึง: var filtered = _.filter (arr, function (item) {return item.id! == 3});
tbh__

2
@tbh__ _()จะสร้างเสื้อคลุมรอบคอลเลกชันซึ่งจะช่วยให้คุณเรียกใช้วิธีการขีดล่าง
Sushanth -

เคยใช้เครื่องหมายขีดเส้นใต้มาหลายปีแล้วฉันไม่เคยรู้เรื่องนี้เลย ขอบคุณ
tbh__


16

ขีดล่างมีเมธอด _without () ที่สมบูรณ์แบบสำหรับการลบรายการออกจากอาร์เรย์โดยเฉพาะอย่างยิ่งถ้าคุณมีวัตถุที่จะลบ

ส่งคืนสำเนาของอาร์เรย์โดยลบอินสแตนซ์ทั้งหมดของค่า

_.without(["bob", "sam", "fred"], "sam");

=> ["bob", "fred"]

ทำงานร่วมกับวัตถุที่ซับซ้อนมากขึ้นเช่นกัน

var bob = { Name: "Bob", Age: 35 };
var sam = { Name: "Sam", Age: 19 };
var fred = { Name: "Fred", Age: 50 };

var people = [bob, sam, fred]

_.without(people, sam);

=> [{ Name: "Bob", Age: 35 }, { Name: "Fred", Age: 50 }];

หากคุณไม่ได้มีรายการที่จะลบเพียงคุณสมบัติของมันคุณสามารถใช้แล้ว_.findWhere_.without


2
หมายเหตุ: ใช้งานได้เพียงเพราะคุณส่งผ่านวัตถุ sam ไปโดยไม่ต้อง หากคุณส่งผ่าน{ Name: "Sam", Age: 19 }ไปที่โดยไม่ใช้แทน sam sam จะไม่ทำงานอีกต่อไป Fiddle
Adam

5

โปรดใช้ความระมัดระวังหากคุณกำลังกรองสตริงและค้นหาตัวกรองที่ไม่สำคัญ _.without () คำนึงถึงขนาดตัวพิมพ์ นอกจากนี้คุณยังสามารถใช้ _.reject () ตามที่แสดงด้านล่าง

var arr = ["test","test1","test2"];

var filtered = _.filter(arr, function(arrItem) {
    return arrItem.toLowerCase() !== "TEST".toLowerCase();
});
console.log(filtered);
// ["test1", "test2"]

var filtered1 = _.without(arr,"TEST");
console.log(filtered1);
// ["test", "test1", "test2"]

var filtered2 = _.reject(arr, function(arrItem){ 
    return arrItem.toLowerCase() === "TEST".toLowerCase();
});
console.log(filtered2);
// ["test1", "test2"]

4

คำตอบอื่น ๆ สร้างสำเนาใหม่ของอาร์เรย์ถ้าคุณต้องการแก้ไขอาร์เรย์ที่คุณสามารถใช้:

arr.splice(_.findIndex(arr, { id: 3 }), 1);

แต่สันนิษฐานว่าองค์ประกอบจะถูกพบภายในอาร์เรย์ (เพราะหากไม่พบก็จะยังคงลบองค์ประกอบสุดท้าย) เพื่อความปลอดภัยคุณสามารถใช้:

var index = _.findIndex(arr, { id: 3 });
if (index > -1) {
    arr.splice(index, 1);
}

2

หรืออีกวิธีที่มีประโยชน์:

_.omit(arr, _.findWhere(arr, {id: 3}));

2 เซ็นต์ของฉัน


1
งดทำงานบนและส่งกลับobject objectดังนั้นจึงไม่ดีสำหรับการทำงานกับArraysที่ที่เราอาจคาดหวังว่าจะได้รับarrayกลับมาหลังจากลบองค์ประกอบ
ScrapCode

1
ดังนั้น_.withoutคือสิ่งที่คุณกำลังมองหา: _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
Nadeem

2

การใช้งานสามารถใช้ธรรมดา JavaScript 's Array#filterวิธีการเช่นนี้

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var filteredArr = arr.filter(obj => obj.id != 3);

console.log(filteredArr);

หรือใช้Array#reduceและArray#concatวิธีการเช่นนี้:

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var reducedArr = arr.reduce((accumulator, currObj) => {
  return (currObj.id != 3) ? accumulator.concat(currObj) : accumulator;
}, []);

console.log(reducedArr);

บันทึก:

  • ทั้งสองนี้เป็นวิธีการทำงานที่บริสุทธิ์ ( เช่นพวกเขาไม่ได้ปรับเปลี่ยนอาร์เรย์ที่มีอยู่)
  • ไม่จำเป็นต้องใช้ไลบรารีภายนอกในวิธีการเหล่านี้ (Vanilla JavaScript ก็เพียงพอ)

0

ฉันเคยลองวิธีนี้

_.filter(data, function(d) { return d.name != 'a' });

อาจมีวิธีที่ดีกว่าเช่นกันกับวิธีแก้ไขปัญหาข้างต้นที่ผู้ใช้เตรียม


0

โดยใช้ underscore.js

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var resultArr = _.reject(arr,{id:3});

console.log(resultArr);

ผลลัพธ์จะเป็น :: [{id:1name:'a'},{id:2,name:'c'}]


-1

คุณสามารถใช้วิธีการปฏิเสธของขีดล่างด้านล่างจะส่งกลับอาร์เรย์ใหม่ซึ่งจะไม่มีอาร์เรย์ที่มีการจับคู่แบบพิเศษ

arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.