การค้นหาอาร์เรย์ Javascript และลบสตริง?


134

ฉันมี:

var array = new Array();
array.push("A");
array.push("B");
array.push("C");

ฉันต้องการที่จะทำสิ่งที่ชอบ:

array.remove("B");

แต่ไม่มีฟังก์ชั่นลบ ฉันจะทำสิ่งนี้ได้อย่างไร


5
การรวมกันของ.indexOf()และ.splice()ควรทำเคล็ดลับ หรืออีกวิธีหนึ่ง, .filter().
Marc B


คำตอบ:


186

ฉันกำลังปรับปรุงเธรดนี้ด้วยโซลูชัน 1 บรรทัดล่าสุด:

let arr = ['A', 'B', 'C'];
arr = arr.filter(e => e !== 'B'); // will return ['A', 'C']

โดยทั่วไปแนวคิดจะกรองอาร์เรย์โดยเลือกองค์ประกอบทั้งหมดที่แตกต่างจากองค์ประกอบที่คุณต้องการลบ

หมายเหตุ: จะลบสิ่งที่เกิดขึ้นทั้งหมด

แก้ไข:

หากคุณต้องการลบเฉพาะครั้งแรกที่เกิดขึ้น:

t = ['A', 'B', 'C', 'B'];
t.splice(t.indexOf('B'), 1); // will return ['B'] and t is now equal to ['A', 'C', 'B']

1
วิธีนี้จะคืนค่าสำเนาของอาร์เรย์ในขณะที่การใช้ Splice จะเอาองค์ประกอบออกมา สิ่งที่คุณเลือกขึ้นอยู่กับบริบท
twhitehead

6
นี่คือสิ่งที่สมบูรณ์แบบสำหรับ Redux stuff ที่คุณต้องการคืนสถานะใหม่
colinwong

@Regis ไม่จริง arr.filter จะส่งคืนอาร์เรย์ใหม่ ดังนั้น arr.filter (e => e! == 'B') จะไม่แก้ไข arr หรือบางทีฉันไม่เข้าใจความคิดเห็นของคุณถูกต้อง?
Tyrannas

มีวิธีการทำเช่นนี้ แต่หยุดในการเกิดครั้งแรก? ดังนั้นถ้ามี 5 'B เพื่อลบออกหรือไม่
Ari

1
@Ari ผมได้ปรับปรุงคำตอบสำหรับการลบเพียงองค์ประกอบหนึ่ง
Tyrannas

171

วน.spliceซ้ำรายการตามลำดับย้อนหลังและใช้วิธีการ

var array = ['A', 'B', 'C']; // Test
var search_term = 'B';

for (var i=array.length-1; i>=0; i--) {
    if (array[i] === search_term) {
        array.splice(i, 1);
        // break;       //<-- Uncomment  if only the first term has to be removed
    }
}

ลำดับย้อนกลับมีความสำคัญเมื่อต้องลบคำค้นหาทั้งหมดที่เกิดขึ้น มิฉะนั้นตัวนับจะเพิ่มขึ้นและคุณจะข้ามองค์ประกอบ

เมื่อมีเพียงการเกิดขึ้นครั้งแรกเท่านั้นที่จะถูกลบออกสิ่งต่อไปนี้จะใช้งานได้:

var index = array.indexOf(search_term);    // <-- Not supported in <IE9
if (index !== -1) {
    array.splice(index, 1);
}

1
ฉันเดาเพราะมันหมายถึงการย้อนกลับเร็วขึ้นเล็กน้อย
Ben Clayton

1
@ BenClayton: ขอบคุณ FWIW ใน JavaScript นั้นไม่เป็นความจริงอย่างน่าเชื่อถือ การนับถอยหลังจะ0ไม่เร็วขึ้นโดยอัตโนมัติเหมือนกับที่อยู่ในนั้นพูดตราบใดที่คุณแคชขีด จำกัด ซึ่งจะทำให้สิ่งต่าง ๆ ซับซ้อนหากคุณทำตามนัดแรกต่อไป (แต่ไม่ใช่ถ้าคุณหยุดมัน)
TJ Crowder

หากเราต้องการความเร็วทำไมไม่ลองใช้ - - : D
Snuffleupagus

11
มันไม่เกี่ยวกับความเร็วเขายังพูดอย่างนั้นในคำตอบของเขา มันเกี่ยวกับองค์ประกอบ SKIPPING หากคุณอยู่ที่ตำแหน่ง 5 และคุณประกบกันตำแหน่งที่ formelry ธาตุตั้งอยู่ที่ตำแหน่ง 6 เป็นตอนที่ 5 ถึงกระนั้นการวนรอบเคาน์เตอร์ของคุณเพิ่มขึ้นการทำซ้ำครั้งถัดไปคือตำแหน่งที่ 6 และที่คุณข้ามรายการ นั่นเป็นเหตุผลที่อยู่ในลำดับย้อนกลับ
amenthes

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

24

รายชื่อหนึ่งสมุทร

ลองแก้ปัญหานี้สำหรับอาร์เรย์นี้:

var array = ['A', 'B', 'C'];

1. ลบเฉพาะรายการแรก: ใช้หากคุณแน่ใจว่ามีรายการอยู่

array.splice(array.indexOf('B'), 1);

2. นำออกล่าสุดเท่านั้น: ใช้หากคุณแน่ใจว่ามีรายการอยู่

array.splice(array.lastIndexOf('B'), 1);

3. ลบเหตุการณ์ทั้งหมด:

array = array.filter(v => v !== 'B'); 

21

การสาธิต

คุณต้องค้นหาตำแหน่งของสิ่งที่คุณต้องการ.indexOf()แล้วลบออกด้วย.splice()

function remove(arr, what) {
    var found = arr.indexOf(what);

    while (found !== -1) {
        arr.splice(found, 1);
        found = arr.indexOf(what);
    }
}

var array = new Array();
array.push("A");
array.push("B");
array.push("C");
    
remove(array, 'B');
alert(array)​​​​;

สิ่งนี้จะดูแลทุกเหตุการณ์


เบราว์เซอร์ที่ไม่สนับสนุน.indexOf()คุณสามารถเพิ่มนี้ไปยังไฟล์จาวาสคริปต์ของคุณ
qwertymk

ใช่หรูหรา หากคุณต้องการตัวเลือกในการลบองค์ประกอบบางอย่างเท่านั้นเช่นรายการแรก: การปรับปรุงเดียวกัน: jsfiddle.net/qpZFd/9
sebilasse

Uncaught ReferenceError: array is not definedผมเคยได้รับข้อผิดพลาดต่อไปนี้: เกิดอะไรขึ้น?
Pathros

หากคุณกำลังจะไปเส้นทางนี้คุณสามารถใช้ประโยชน์จากการเพิ่ม.indexOf()เพียงเล็กน้อย หากคุณผ่านfoundเป็นอาร์กิวเมนต์ที่สองในการ.indexOf()โทรภายใน while-loopองค์ประกอบในอาร์เรย์ที่ถูกตรวจสอบแล้วและสิ้นสุดลงไม่เท่ากันจะไม่ถูกตรวจสอบอีกครั้ง: found = arr.indexOf(what, found);
pimmhogeling

14

ง่ายดาย

array.splice(array.indexOf(item), 1);

ใช่ยกเว้น indexOf จะกลับมา-1หากไม่พบสิ่งใดและใครเลยรอยต่อจะลบ 1 องค์ประกอบจากปลายอาร์เรย์
Ricky Spanish

2

ทางออกที่ง่าย (ES6)

หากคุณไม่มีองค์ประกอบที่ซ้ำกัน

Array.prototype.remove = function(elem) {
  var indexElement = this.findIndex(el => el === elem);
  if (indexElement != -1)
    this.splice(indexElement, 1);
  return this;
};   

การสาธิตออนไลน์ (ซอ)


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

1

คุณต้องเขียนว่าคุณเป็นเจ้าของลบ คุณสามารถวนซ้ำแถวลำดับคว้าดัชนีของรายการที่คุณต้องการลบและใช้spliceเพื่อลบออก

อีกวิธีหนึ่งคุณสามารถสร้างอาร์เรย์ใหม่วนซ้ำอาร์เรย์ปัจจุบันและถ้าวัตถุปัจจุบันไม่ตรงกับสิ่งที่คุณต้องการเอาออกให้ใส่มันในอาร์เรย์ใหม่


1

ใช้:

array.splice(2, 1);

สิ่งนี้จะลบหนึ่งรายการจากอาร์เรย์เริ่มต้นที่ดัชนี 2 (รายการที่ 3)


1
ที่จริงมันจะลบรายการที่สองออกจากอาร์เรย์โดยดัชนีจะเริ่มจากศูนย์ คำสั่งนี้มีความกำกวมตัวอย่างที่ง่ายกว่าอาจเป็นไปได้ว่าarray.splice(2,1)จะลบ 1 รายการที่ดัชนี 2 จากอาร์เรย์ ตรวจสอบhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/spliceสำหรับรายละเอียดเพิ่มเติม
imdzeeshan

1
const changedArray = array.filter( function(value) {
  return value !== 'B'
});

หรือคุณสามารถใช้:

const changedArray = array.filter( (value) => value === 'B');

อาร์เรย์ที่เปลี่ยนไปจะมีค่าที่ไม่มี 'B'


0

ใช้ array.splice

/*array.splice(index , howMany[, element1[, ...[, elementN]]])

array.splice(index) // SpiderMonkey/Firefox extension*/

array.splice(1,1)

ที่มา: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice


เครื่องหมายจุลภาคระหว่างarrayและspliceจะต้องมีจุด
Rob W

พยายามแก้ไขให้ถูกต้อง แต่นโยบายของ SO ระบุว่าการแก้ไขจะต้องมีความยาว 6 ตัวอักษรขึ้นไป: /
ben_nuttall
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.