Hapus item dari array menggunakan UnderscoreJS

137

Katakanlah saya punya kode ini

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

dan saya ingin menghapus item dengan id = 3 dari array. Apakah ada cara untuk melakukan ini tanpa splicing? Bolehkah sesuatu menggunakan garis bawah atau sesuatu seperti itu?

Terima kasih!

memanjat
sumber
Jika Anda tidak ingin membuat array baru, splicing adalah satu-satunya pilihan. Saya yakin garis bawah menggunakannya juga (secara internal, jika ada metode seperti itu).
Felix Kling
6
Apa yang salah dengan splicing?
Šime Vidas
Sudahkah Anda memeriksa referensi garis bawah?
Šime Vidas
Hanya menggunakan JavaScript biasa, ini adalah duplikat dari menghapus objek dari array oleh properti objek .
Felix Kling
5
juga bukan duplikat karena memiliki tag untuk underscore.js
Garis M Suero

Jawaban:

279

Hanya menggunakan JavaScript biasa, ini sudah dijawab: hapus objek dari array oleh properti objek .

Menggunakan underscore.js, Anda dapat menggabungkan .findWheredengan .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>

Meskipun, karena Anda membuat array baru dalam kasus ini, Anda bisa menggunakan _.filteratau Array.prototype.filterfungsi asli (seperti yang ditunjukkan pada pertanyaan lain). Maka Anda hanya akan mengulangi array sekali daripada berpotensi dua kali seperti di sini.

Jika Anda ingin memodifikasi array di tempat , Anda harus menggunakan .splice. Ini juga ditunjukkan dalam pertanyaan lain dan undescore sepertinya tidak menyediakan fungsi yang berguna untuk itu.

Felix Kling
sumber
1
Yap ini berfungsi dengan baik, saya memang pergi ke dokumentasi garis bawah tetapi tidak begitu mengerti bagaimana mencabutnya tanpa. Terima kasih!
memanjat
10
Bukankah _.reject atau _.filter () jauh lebih efisien di sini? Anda akan berakhir dengan dua iterasi daftar hanya untuk mengeluarkan satu item.
Rick Strahl
1
Ini mungkin duplikat tetapi ini adalah jawaban yang lebih baik.
Michael J. Calkins
2
@ RickStrahl Anda benar. _.rejectsepertinya pilihan yang lebih baik di sini.
Tarik
1
@lukaserat untuk membuka elemen terakhir, gunakan arr.pop()...
Emile Bergeron
96

Anda dapat menggunakan Garis Bawah .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
    });

Dapat juga ditulis sebagai:

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

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

Periksa Fiddle

Anda juga bisa menggunakan .reject

Sushanth -
sumber
Saya pikir Anda maksud: var filtered = _.filter (arr, function (item) {return item.id! == 3});
tbh__
2
@ tbh__ _()akan membuat wrapper di sekitar koleksi yang memungkinkan Anda menggunakan metode garis bawah.
Sushanth -
Sudah menggunakan garis bawah selama bertahun-tahun, saya tidak pernah tahu ini. Terima kasih
tbh__
39

Gunakan Garis Bawah _.reject():

arr = _.reject(arr, function(d){ return d.id === 3; });
greenafrican
sumber
dengan es6 yang dapat Anda lakukanarr = _.reject(arr, d => d.id === 3 );
greenafrican
16

Underscore memiliki metode _without () yang sempurna untuk menghapus item dari array, terutama jika Anda memiliki objek untuk dihapus.

Mengembalikan salinan array dengan semua instance nilai yang dihapus.

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

=> ["bob", "fred"]

Bekerja dengan benda yang lebih kompleks juga.

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

Jika Anda tidak memiliki item untuk dihapus, hanya properti itu, Anda dapat menggunakan _.findWheredan kemudian _.without.

PeteGO
sumber
2
Catatan: ini hanya berfungsi karena Anda melewatkan objek sam ke luar. Jika Anda beralih { Name: "Sam", Age: 19 }ke tanpa, alih-alih variabel sam, itu tidak lagi berfungsi. Fiddle
Adam
5

Harap berhati-hati jika Anda memfilter string dan mencari filter case sensitif. _.without () peka huruf besar-kecil. Anda juga dapat menggunakan _.reject () seperti yang ditunjukkan di bawah ini.

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"]
Srihari Sridharan
sumber
4

Jawaban lain membuat salinan array baru, jika Anda ingin memodifikasi array di tempat yang dapat Anda gunakan:

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

Tetapi itu mengasumsikan bahwa elemen akan selalu ditemukan di dalam array (karena jika tidak ditemukan masih akan menghapus elemen terakhir). Agar aman, Anda dapat menggunakan:

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

atau cara praktis lain:

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

2 sen saya

Nadeem
sumber
1
mengabaikan bekerja objectdan mengembalikan sebuah object. karenanya tidak terlalu baik untuk bekerja dengan Arraystempat yang mungkin kita harapkan untuk mendapatkan arraykembali setelah menghapus elemen.
ScrapCode
1
Jadi, _tidak ada pada Anda sedang melihat: _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
Nadeem
2

Gunakan dapat menggunakan plain JavaScript 's Array#filtermetode seperti ini:

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

Atau, gunakan Array#reducedan Array#concatmetode seperti ini:

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

CATATAN:

  • Keduanya adalah pendekatan fungsional murni ( yaitu mereka tidak mengubah array yang ada).
  • Tidak, perpustakaan eksternal diperlukan dalam pendekatan ini (JavaScript Vanilla sudah cukup).
BlackBeard
sumber
0

Saya dulu mencoba metode ini

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

Mungkin ada metode yang lebih baik juga seperti solusi di atas yang disediakan oleh pengguna

Bastin Robin
sumber
0

Dengan Menggunakan 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);

Hasilnya akan :: [{id:1name:'a'},{id:2,name:'c'}]

Anand Tamizh
sumber
-1

Anda dapat menggunakan metode tolak Garis Bawah, di bawah ini akan mengembalikan array baru yang tidak akan memiliki array dengan kecocokan tertentu

arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
BAJA
sumber