ใน Javascript ฉันจะตรวจสอบได้อย่างไรว่าอาร์เรย์มีค่าที่ซ้ำกัน


95

สามารถทำซ้ำได้:
วิธีที่ง่ายที่สุดในการค้นหาค่าที่ซ้ำกันในอาร์เรย์จาวาสคริปต์

ฉันจะตรวจสอบว่าอาร์เรย์มีค่าซ้ำกันได้อย่างไร

หากองค์ประกอบบางอย่างในอาร์เรย์เหมือนกันให้คืนค่าจริง มิฉะนั้นให้ส่งคืนเท็จ

['hello','goodbye','hey'] //return false because no duplicates exist
['hello','goodbye','hello'] // return true because duplicates exist

สังเกตว่าฉันไม่สนใจเกี่ยวกับการค้นหาการทำซ้ำเพียงต้องการผลลัพธ์บูลีนว่าอาร์เรย์มีการทำซ้ำ



2
ฉันไม่ต้องการให้นำรายการที่ซ้ำกันออก ฉันแค่อยากรู้ว่าจริงหรือเท็จถ้ารายการมีรายการซ้ำกัน
user847495

7
คำถามนี้ไม่ซ้ำกัน เนื่องจาก @ user847495 เพียงต้องการตรวจสอบว่ามีรายการที่ซ้ำกันอยู่หรือไม่การแก้ปัญหาจึงเร็ว / ง่ายกว่าที่จำเป็นในการค้นหารายการที่ซ้ำกันทั้งหมด ตัวอย่างเช่นคุณสามารถทำได้: codr.io/v/bvzxhqm
alden

2
ใช้ขีดล่างเทคนิคง่ายๆvar test=['hello','goodbye','hello'] ; if ( test.length != _.unique(test).length ) { // some code }
สายราม

4
ไม่ซ้ำกับคำถามที่ทำเครื่องหมายไว้ โปรดใส่ใจก่อนทำเครื่องหมายคำถามดังกล่าว
John Weisz

คำตอบ:


222

หากคุณมีสภาพแวดล้อม ES2015 (ตามที่เขียนนี้: io.js, IE11, Chrome, Firefox, WebKit ทุกคืน) สิ่งต่อไปนี้จะใช้งานได้และจะเร็ว (ได้แก่ O (n)):

function hasDuplicates(array) {
    return (new Set(array)).size !== array.length;
}

หากคุณต้องการเพียงค่าสตริงในอาร์เรย์สิ่งต่อไปนี้จะใช้ได้:

function hasDuplicates(array) {
    var valuesSoFar = Object.create(null);
    for (var i = 0; i < array.length; ++i) {
        var value = array[i];
        if (value in valuesSoFar) {
            return true;
        }
        valuesSoFar[value] = true;
    }
    return false;
}

เราใช้ "ตารางแฮช" valuesSoFarซึ่งมีคีย์เป็นค่าที่เราเห็นในอาร์เรย์จนถึงตอนนี้ เราทำการค้นหาโดยใช้inเพื่อดูว่าค่านั้นถูกตรวจพบแล้วหรือยัง trueถ้าเป็นเช่นนั้นเราประกันตัวออกจากวงและผลตอบแทน


หากคุณต้องการฟังก์ชันที่ใช้งานได้มากกว่าค่าสตริงสิ่งต่อไปนี้จะใช้งานได้ แต่ไม่สามารถใช้งานได้ เป็น O (n 2 ) แทนที่จะเป็น O (n)

function hasDuplicates(array) {
    var valuesSoFar = [];
    for (var i = 0; i < array.length; ++i) {
        var value = array[i];
        if (valuesSoFar.indexOf(value) !== -1) {
            return true;
        }
        valuesSoFar.push(value);
    }
    return false;
}

ความแตกต่างก็คือเราใช้อาร์เรย์แทนตารางแฮชvaluesSoFarเนื่องจาก JavaScript "ตารางแฮช" (เช่นอ็อบเจ็กต์) มีคีย์สตริง ซึ่งหมายความว่าเราสูญเสีย O นี้ (1) เวลาในการค้นหาของinแทนที่จะได้รับ O (n) indexOfเวลาในการค้นหาของ


3
เกี่ยวกับตัวอย่างแรกที่คุณให้มา การตรวจสอบความถูกต้องไม่ตรงกับวิธีอื่น ๆ หรือไม่? หากตั้งชื่อฟังก์ชั่นของคุณhasDuplicatesควรตรวจสอบว่าขนาดของชุดนั้นหดลงจริงหรือไม่ในระหว่างขั้นตอนการแคสต์ใช่ไหม ดังนั้นตัวดำเนินการบูลีนจึงควรเป็น!==ไม่ใช่===
Tim Daubenschütz

กรุณาแก้ไข ฉันไม่สามารถแก้ไขได้เนื่องจากฉันไม่ได้เปลี่ยนตัวอักษรเกิน 6 ตัว
Tim Daubenschütz

1
ตามMDN IE11 ไม่สนับสนุนตัวสร้างที่ใช้ในตัวอย่างแรก
adam77

เวอร์ชัน JS ปกติจะส่งคืนtrueอาร์เรย์ต่อไปนี้:[1, '1']
Kunal

ดังนั้น "ถ้าคุณต้องการเฉพาะค่าสตริงในอาร์เรย์" ที่นำหน้าคำตอบ
Domenic

4

อีกวิธีหนึ่ง (สำหรับองค์ประกอบวัตถุ / อาร์เรย์ภายในอาร์เรย์1 ) อาจเป็น2 :

function chkDuplicates(arr,justCheck){
  var len = arr.length, tmp = {}, arrtmp = arr.slice(), dupes = [];
  arrtmp.sort();
  while(len--){
   var val = arrtmp[len];
   if (/nul|nan|infini/i.test(String(val))){
     val = String(val);
    }
    if (tmp[JSON.stringify(val)]){
       if (justCheck) {return true;}
       dupes.push(val);
    }
    tmp[JSON.stringify(val)] = true;
  }
  return justCheck ? false : dupes.length ? dupes : null;
}
//usages
chkDuplicates([1,2,3,4,5],true);                           //=> false
chkDuplicates([1,2,3,4,5,9,10,5,1,2],true);                //=> true
chkDuplicates([{a:1,b:2},1,2,3,4,{a:1,b:2},[1,2,3]],true); //=> true
chkDuplicates([null,1,2,3,4,{a:1,b:2},NaN],true);          //=> false
chkDuplicates([1,2,3,4,5,1,2]);                            //=> [1,2]
chkDuplicates([1,2,3,4,5]);                                //=> null

ดูสิ่งนี้ด้วย...

1ต้องการเบราว์เซอร์ที่รองรับ JSON หรือไลบรารี JSONถ้าไม่
2 แก้ไข:สามารถใช้ฟังก์ชันสำหรับการตรวจสอบอย่างง่ายหรือเพื่อส่งคืนอาร์เรย์ของค่าที่ซ้ำกันได้


3
ปัญหาที่ไม่แสดงตัวตนที่ควรทราบ: 1) เปลี่ยนอาร์เรย์เดิมที่จะจัดเรียง 2) ไม่ได้แยกความแตกต่างระหว่างnull, NaN, Infinity, +Infinityและ-Infinity; 3) วัตถุจะถือว่าเท่ากันหากมีคุณสมบัติของตัวเองเหมือนกันแม้ว่าจะมีต้นแบบต่างกันก็ตาม
Domenic

1
@Domenic: ใช่ควรพูดถึงมัน แก้ไขเพื่อหลีกเลี่ยงการกลายพันธุ์ของอาร์เรย์เดิม
KooiInc

@Domenic: แก้ไขสำหรับ null / NaN / [+/-] Infinity โปรดดูการแก้ไข
KooiInc

@Domenic: ประเด็นที่ 3) ไม่ใช่ปัญหาสำหรับฉันเพราะมันเป็นสิ่งที่ฉันต้องการ ฉันไม่สนใจต้นแบบแค่ค่านิยม
กลัว

-3

ฉันได้ค้นหาคุณในอินเทอร์เน็ตเล็กน้อยและพบลิงก์ที่มีประโยชน์นี้

วิธีที่ง่ายที่สุดในการค้นหาค่าที่ซ้ำกันในอาร์เรย์ JavaScript

คุณสามารถปรับโค้ดตัวอย่างที่ให้ไว้ในลิงก์ด้านบนโดยได้รับความอนุเคราะห์จาก "swilliams" กับโซลูชันของคุณ

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