ตรวจสอบว่าอาร์เรย์มีองค์ประกอบใด ๆ ของอาร์เรย์อื่นใน JavaScript


406

ฉันมีอาเรย์เป้าหมาย["apple","banana","orange"]และต้องการตรวจสอบว่าอาเรย์อื่นมีองค์ประกอบอาเรย์ตัวใดตัวหนึ่งหรือไม่

ตัวอย่างเช่น:

["apple","grape"] //returns true;

["apple","banana","pineapple"] //returns true;

["grape", "pineapple"] //returns false;

ฉันจะทำใน JavaScript ได้อย่างไร


3
ใช้การforวนซ้ำแล้ววนซ้ำไปยังอาร์เรย์เป้าหมาย หากทุกองค์ประกอบมีอยู่ภายในอาร์เรย์ปัจจุบัน (ใช้current.indexOf(elem) !== -1)แล้วก็จะอยู่ในนั้นทั้งหมด
Blender

21
@Alex เลือกคำตอบเพื่อนมันเป็นเรื่องหยาบคายที่จะไม่ตอบคำถามโดยเฉพาะกับคำตอบที่ดีมากมาย ฉันจะเลือกขีดเส้นใต้ / lodash ถ้าฉันเป็นคุณ
Leon Gaban

1
@LeonGaban ฉันไม่เห็นด้วย ฉันจะไม่นำเข้าห้องสมุดเพื่อดำเนินการนี้
devpato

2
@devpato ใช่เปลี่ยนใจแล้วโซลูชัน ES6 คือสิ่งที่ฉันโปรดปราน
Leon Gaban

เกี่ยวกับ arr1.some (el1 => arr2.includes (el1)); ?
Walaszka

คำตอบ:


551

วานิลลา JS

ES2016:

const found = arr1.some(r=> arr2.includes(r))

ES6:

const found = arr1.some(r=> arr2.indexOf(r) >= 0)

มันทำงานอย่างไร

some(..)ตรวจสอบแต่ละองค์ประกอบของอาเรย์กับฟังก์ชั่นการทดสอบและส่งกลับค่าจริงถ้าองค์ประกอบใดของอาเรย์ผ่านฟังก์ชั่นการทดสอบมิฉะนั้นจะส่งกลับเท็จ indexOf(..) >= 0และincludes(..)ทั้งสองกลับเป็นจริงถ้าอาร์กิวเมนต์ที่กำหนดมีอยู่ในอาร์เรย์


48
รหัสนี้ต้องการคำอธิบาย - วิธีนี้ใช้ได้ผล แต่ไม่มีค่าเพราะไม่มีใครเรียนรู้อะไรเลย
TolMera

6
Array.prototype.some () ตรวจสอบแต่ละองค์ประกอบของอาเรย์กับฟังก์ชั่นการทดสอบและส่งคืนtrueถ้าองค์ประกอบใดของอาเรย์ผ่านฟังก์ชั่นการทดสอบ falseมิฉะนั้นก็จะส่งกลับ
Hendeca

2
นี่ควรเป็นคำตอบที่ถูกต้อง! อันยิ่งใหญ่ที่ใช้ ES6
Nacho

1
เป็นที่คาดหวังหรือไม่ว่าผลลัพธ์ของฉันจะ[false, false, false]เป็นอาร์เรย์ว่างเปล่า[]?
แบทแมน

@Batman: ผลลัพธ์เป็นจริง / เท็จ แต่คุณสามารถปรับแก้ปัญหาจาก Mr. skyisred
0zkr PM

230

วานิลลา js

/**
 * @description determine if an array contains one or more items from another array.
 * @param {array} haystack the array to search.
 * @param {array} arr the array providing items to check for in the haystack.
 * @return {boolean} true|false if haystack contains at least one item from arr.
 */
var findOne = function (haystack, arr) {
    return arr.some(function (v) {
        return haystack.indexOf(v) >= 0;
    });
};

10
ทางออกที่ดี! some()คือ rad ออกจากทันทีที่พบสิ่งที่ต้องการ
averydev

6
tidier เหตุการณ์เช่นนี้arr.some(v=> haystack.indexOf(v) >= 0)
พอลกริมชอว์

85
มีให้ใน ES2016arr.some(v => haystack.includes(v))
loganfsmyth

5
arr1.some(v => arr2.indexOf(v) >= 0)ในหนึ่งบรรทัด
webjay

1
สำหรับตอนนี้อาจเป็นการดีที่สุดที่จะหลีกเลี่ยงการใช้includesเนื่องจากดูเหมือนไม่รองรับ IE: stackoverflow.com/questions/36574351/…
Shafique Jamal

72

หากคุณไม่ได้ต่อต้านการใช้ libray http://underscorejs.org/มีวิธีการแยกซึ่งสามารถทำให้สิ่งนี้ง่ายขึ้น:

var _ = require('underscore');

var target = [ 'apple', 'orange', 'banana'];
var fruit2 = [ 'apple', 'orange', 'mango'];
var fruit3 = [ 'mango', 'lemon', 'pineapple'];
var fruit4 = [ 'orange', 'lemon', 'grapes'];

console.log(_.intersection(target, fruit2)); //returns [apple, orange]
console.log(_.intersection(target, fruit3)); //returns []
console.log(_.intersection(target, fruit4)); //returns [orange]

ฟังก์ชั่นการแยกจะส่งกลับอาร์เรย์ใหม่ที่มีรายการที่จับคู่และถ้าไม่ตรงกับมันจะส่งกลับอาร์เรย์ที่ว่างเปล่า


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

1
lodash สามารถอ่านได้มากขึ้นจากนั้นวานิลลา Javascript, libs อย่างที่ Ramda ควรใช้แทน vanilla imho ดีกว่าสำหรับนักพัฒนาทั้งหมด ...
Leon Gaban

52

ES6 (เร็วที่สุด)

const a = ['a', 'b', 'c'];
const b = ['c', 'a', 'd'];
a.some(v=> b.indexOf(v) !== -1)

ES2016

const a = ['a', 'b', 'c'];
const b = ['c', 'a', 'd'];
a.some(v => b.includes(v));

ขีด

const a = ['a', 'b', 'c'];
const b = ['c', 'a', 'd'];
_.intersection(a, b)

DEMO: https://jsfiddle.net/r257wuv5/

jsPerf: https://jsperf.com/array-contain-any-element-of-another-array


1
นี่เป็นวิธีแก้ปัญหาที่ง่ายและชัดเจนที่สุด
strider

ฉันรู้ว่าฉันมาสายจริงๆแล้ว แต่เพื่อตรวจสอบคอนโซลว่า JSFiddle เพิ่ม JQuery Edge และเปิด Firebug Lite
Rojo

JSperf ลิงก์เสียหาย
DarckBlezzer

ความซับซ้อนของเวลาและพื้นที่แตกต่างกันหรือไม่? อะไรจะเป็นทางออกที่ดีที่สุดเกี่ยวกับความซับซ้อน?
nacho

41

หากคุณไม่ต้องการการบีบบังคับประเภท (เนื่องจากการใช้งานindexOf) คุณสามารถลองสิ่งต่อไปนี้:

var arr = [1, 2, 3];
var check = [3, 4];

var found = false;
for (var i = 0; i < check.length; i++) {
    if (arr.indexOf(check[i]) > -1) {
        found = true;
        break;
    }
}
console.log(found);

arrมีรายการเป้าหมายอยู่ที่ไหน ในตอนท้ายfoundจะแสดงว่าอาร์เรย์ที่สองมีการแข่งขันอย่างน้อยหนึ่งครั้งกับเป้าหมายหรือไม่

แน่นอนคุณสามารถสลับตัวเลขสำหรับสิ่งที่คุณต้องการใช้ - สตริงนั้นดีเช่นตัวอย่างของคุณ

และในตัวอย่างเฉพาะของฉันผลลัพธ์ควรเป็นtrueเพราะอาร์เรย์ที่สอง3มีอยู่ในเป้าหมาย


UPDATE:

นี่คือวิธีที่ฉันจะจัดระเบียบเป็นฟังก์ชั่น (มีการเปลี่ยนแปลงเล็กน้อยจากก่อน):

var anyMatchInArray = (function () {
    "use strict";

    var targetArray, func;

    targetArray = ["apple", "banana", "orange"];
    func = function (checkerArray) {
        var found = false;
        for (var i = 0, j = checkerArray.length; !found && i < j; i++) {
            if (targetArray.indexOf(checkerArray[i]) > -1) {
                found = true;
            }
        }
        return found;
    };

    return func;
}());

DEMO: http://jsfiddle.net/u8Bzt/

ในกรณีนี้ฟังก์ชั่นสามารถปรับเปลี่ยนให้targetArrayส่งผ่านเป็นอาร์กิวเมนต์แทนฮาร์ดโค้ดในการปิด


UPDATE2:

ในขณะที่วิธีการแก้ปัญหาข้างต้นของฉันอาจทำงานได้และเป็น (หวังมากกว่า) อ่านได้ฉันเชื่อว่าวิธีที่ "ดีกว่า" ในการจัดการกับแนวคิดที่ฉันอธิบายคือการทำสิ่งที่แตกต่างกันเล็กน้อย "ปัญหา" ด้วยการแก้ปัญหาข้างต้นคือการindexOfที่วงในทำให้อาร์เรย์เป้าหมายที่จะวนรอบอย่างสมบูรณ์สำหรับทุกรายการในอาร์เรย์อื่น สิ่งนี้สามารถ "แก้ไข" ได้อย่างง่ายดายโดยใช้ "การค้นหา" (แผนที่ ... ตัวอักษรของวัตถุ JavaScript) สิ่งนี้อนุญาตให้วนซ้ำสองลูปง่ายกว่าแต่ละอาร์เรย์ นี่คือตัวอย่าง:

var anyMatchInArray = function (target, toMatch) {
    "use strict";

    var found, targetMap, i, j, cur;

    found = false;
    targetMap = {};

    // Put all values in the `target` array into a map, where
    //  the keys are the values from the array
    for (i = 0, j = target.length; i < j; i++) {
        cur = target[i];
        targetMap[cur] = true;
    }

    // Loop over all items in the `toMatch` array and see if any of
    //  their values are in the map from before
    for (i = 0, j = toMatch.length; !found && (i < j); i++) {
        cur = toMatch[i];
        found = !!targetMap[cur];
        // If found, `targetMap[cur]` will return true, otherwise it
        //  will return `undefined`...that's what the `!!` is for
    }

    return found;
};

DEMO: http://jsfiddle.net/5Lv9v/

ข้อเสียของโซลูชันนี้คือสามารถใช้ตัวเลขและสตริง (และบูลีน) ได้อย่างถูกต้องเท่านั้น (เพราะถูกแปลงเป็นค่า (โดยปริยาย) เป็นสตริงและตั้งค่าเป็นคีย์ของแผนผังการค้นหา สิ่งนี้ไม่ดี / เป็นไปได้ / ทำได้อย่างง่ายดายสำหรับค่าที่ไม่ใช่ตัวอักษร


2
ตัวอย่างที่ดีเยี่ยมตัวอย่างที่สองนั้นยอดเยี่ยมมาก
Sorin Haidau

ทำไมคุณใช้ลูปในขณะที่คุณสามารถใช้บางส่วนหรือ findIndex
ฉันเอง ... อเล็กซ์

1
"บางคน" ทำให้รหัสง่ายขึ้นอย่างมาก นอกจากนี้ anyMatchInArray ([1,2,3, "cats", "4"], ["1", 4]) จะเป็นจริง สุดท้ายนี้อาจมีประสิทธิภาพมากกว่าหากคุณมีการค้นหาจำนวนมากและแคชเป้าหมาย ถึงกระนั้นก็ตามอาจมีการเพิ่มประสิทธิภาพได้ ตัวอย่างเช่นฉันเดาว่า "found = toMatch [i]! == undefined" จะมีประสิทธิภาพมากกว่าและในบางกรณีจะดีกว่า (เพื่อที่คุณจะไม่ประเมิน "" หรือ 0 เป็นเท็จ)
csga5000

"ไม่งั้นมันจะกลับมาundefined... นั่นคือสิ่งที่!!มีไว้เพื่อ" - ผิดปกติ !มันจะกลับฝ่ายค้านบูลของ
AlienWebguy

41

โซลูชัน ES6:

let arr1 = [1, 2, 3];
let arr2 = [2, 3];

let isFounded = arr1.some( ai => arr2.includes(ai) );

ไม่เหมือน: ต้องมีค่าทั้งหมด

let allFounded = arr2.every( ai => arr1.includes(ai) );

หวังว่าจะเป็นประโยชน์


มีวิธีใดที่จะได้รับค่าดัชนีของarra2จากarray1 หรือไม่?
Anzil khaN

1
ในกรณีนี้เราสามารถใช้ "ตัวกรอง" แทน "บางส่วน" จากนั้นมันจะส่งคืนอาร์เรย์แทนบูลีนและคุณสามารถเข้าถึงค่าจากที่นั่นได้อย่างง่ายดาย
tanvir993

29

คุณสามารถใช้lodashและทำ:

_.intersection(originalTarget, arrayToCheck).length > 0

ตั้งค่าการตัดกันทั้งสองคอลเลกชันเพื่อสร้างอาร์เรย์ขององค์ประกอบที่เหมือนกัน


มันไม่ได้ดีที่สุดในแง่ของประสิทธิภาพเนื่องจากสำหรับปัญหานี้มันก็เพียงพอที่จะหาคู่แรกในขณะที่intersectionจะทำการเปรียบเทียบแม้หลังจากค้นหาคู่แรกเพื่อค้นหาพวกเขาทั้งหมด มันก็เหมือนกับการใช้เมื่อคุณต้องการเพียงแค่filter find
Alexander

29

ใช้ตัวกรอง / indexOf :

function containsAny(source,target)
{
    var result = source.filter(function(item){ return target.indexOf(item) > -1});   
    return (result.length > 0);  
}    


//results

var fruits = ["apple","banana","orange"];


console.log(containsAny(fruits,["apple","grape"]));

console.log(containsAny(fruits,["apple","banana","pineapple"]));

console.log(containsAny(fruits,["grape", "pineapple"]));


สิ่งนี้ได้รับความเดือดร้อนจากปัญหาเดียวกันกับฟังก์ชั่นห้องสมุดเช่น _.intersection โดยที่มันจะยังคงค้นหาการจับคู่ต่อไปแม้จะหาแล้วก็ตาม สำหรับอาร์เรย์ขนาดเล็กอย่างชัดเจนมันไม่สำคัญว่า
JHH

13
const areCommonElements = (arr1, arr2) => {
    const arr2Set = new Set(arr2);
    return arr1.some(el => arr2Set.has(el));
};

หรือคุณสามารถมีประสิทธิภาพที่ดีขึ้นหากคุณพบว่าสองอาร์เรย์นี้นานกว่าและสร้างSetอาร์เรย์ที่ยาวที่สุดในขณะที่ใช้someวิธีการกับอาร์เรย์ที่สั้นที่สุด:

const areCommonElements = (arr1, arr2) => {
    const [shortArr, longArr] = (arr1.length < arr2.length) ? [arr1, arr2] : [arr2, arr1];
    const longArrSet = new Set(longArr);
    return shortArr.some(el => longArrSet.has(el));
};

3
ในขณะที่ผู้คนกำลังโพสต์วิธีแก้ปัญหาด้วยการซ้อนกันindexOfและincludesคุณเป็นคนแรกที่ตอบคำถามด้วยชุดการตั้งค่าที่มีประสิทธิภาพมากขึ้นโดยใช้ native Set4 ปีหลังจากเปิดตัวใน EcmaScript +1
trincot

9

ฉันพบไวยากรณ์สั้นและหวานนี้เพื่อจับคู่องค์ประกอบทั้งหมดหรือบางส่วนระหว่างสองอาร์เรย์ ตัวอย่างเช่น

// หรือการทำงาน ค้นหาว่ามีองค์ประกอบใด ๆ ของ array2 อยู่ใน array1 สิ่งนี้จะกลับมาทันทีที่มีการแข่งขันครั้งแรกเนื่องจากวิธีการบางอย่างแตกเมื่อฟังก์ชันส่งคืน TRUE

let array1 = ['a', 'b', 'c', 'd', 'e'], array2 = ['a', 'b'];

console.log(array2.some(ele => array1.includes(ele)));

// พิมพ์ TRUE

// และการทำงาน ค้นหาว่ามีองค์ประกอบทั้งหมดของ array2 อยู่ใน array1 หรือไม่ สิ่งนี้จะกลับมาทันทีที่ไม่มีการจับคู่ครั้งแรกเนื่องจากวิธีการบางอย่างจะแตกเมื่อฟังก์ชันส่งคืน TRUE

let array1 = ['a', 'b', 'c', 'd', 'e'], array2 = ['a', 'x'];

console.log(!array2.some(ele => !array1.includes(ele)));

// พิมพ์ FALSE

หวังว่าจะช่วยให้ใครบางคนในอนาคต!


ฉันชอบส่วนที่สองของคำถามเพื่อให้มันทำงานกับ ES5 ได้หรือไม่:! array2.some (ฟังก์ชั่น (ele) {return array1.indexOf (ele) === -1});
Friesgaard

6

คุณสามารถใช้การเรียก Array.prototype.some ซ้อนกัน นี่เป็นข้อดีที่จะประกันตัวในนัดแรกแทนที่จะเป็นโซลูชั่นอื่น ๆ ที่จะวิ่งผ่านลูปซ้อนกันแบบเต็ม

เช่น.

var arr = [1, 2, 3];
var match = [2, 4];

var hasMatch = arr.some(a => match.some(m => a === m));

4

นี่เป็นกรณีที่น่าสนใจที่ฉันคิดว่าฉันควรแบ่งปัน

สมมติว่าคุณมีอาร์เรย์ของวัตถุและอาร์เรย์ของตัวกรองที่เลือก

let arr = [
  { id: 'x', tags: ['foo'] },
  { id: 'y', tags: ['foo', 'bar'] },
  { id: 'z', tags: ['baz'] }
];

const filters = ['foo'];

เมื่อต้องการใช้ตัวกรองที่เลือกกับโครงสร้างนี้เราสามารถทำได้

if (filters.length > 0)
  arr = arr.filter(obj =>
    obj.tags.some(tag => filters.includes(tag))
  );

// [
//   { id: 'x', tags: ['foo'] },
//   { id: 'y', tags: ['foo', 'bar'] }
// ]

4

ฉันเขียนวิธีแก้ปัญหา 3 ข้อ เป็นหลักพวกเขาทำเช่นเดียวกัน trueพวกเขากลับจริงเร็วที่สุดเท่าที่พวกเขาได้รับ ฉันเขียน 3 โซลูชั่นเพื่อแสดงวิธีที่ต่างกัน 3 วิธี ตอนนี้มันขึ้นอยู่กับสิ่งที่คุณชอบมากขึ้น คุณสามารถใช้performance.now ()เพื่อตรวจสอบประสิทธิภาพของโซลูชันหนึ่งรายการหรืออีกโซลูชันหนึ่ง ในโซลูชันของฉันฉันกำลังตรวจสอบว่าอาเรย์ใดที่ใหญ่ที่สุดและอันที่เล็กที่สุดเพื่อให้การดำเนินการมีประสิทธิภาพมากขึ้น

วิธีที่ 3 อาจไม่ใช่วิธีที่น่ารัก แต่มีประสิทธิภาพ ฉันตัดสินใจที่จะเพิ่มเพราะในการสัมภาษณ์การเข้ารหัสบางอย่างคุณไม่ได้รับอนุญาตให้ใช้วิธีการในตัว

สุดท้ายแน่ใจว่า ... เราสามารถขึ้นมาด้วยวิธีการแก้ปัญหามี 2 ซ้อนสำหรับลูป (วิธีบังคับเดรัจฉาน) แต่คุณต้องการหลีกเลี่ยงการว่าเป็นเพราะความซับซ้อนของเวลาที่ไม่ดีO (n ^ 2)

บันทึก:

แทนที่จะใช้.includes()อย่างที่คนอื่นทำคุณสามารถ .indexOf()ใช้ได้ ถ้าคุณแค่ตรวจสอบว่าค่ามากกว่า 0 ถ้าไม่มีค่าจะให้ -1 ถ้ามันมีอยู่มันจะให้คุณมากกว่า 0

indexOf () vs include ()

อันไหนมีประสิทธิภาพดีกว่ากัน? indexOf()สำหรับนิด ๆ หน่อย ๆ แต่รวมถึงสามารถอ่านได้ในความคิดของฉัน

ถ้าฉันไม่ผิด.includes()และindexOf()ใช้ลูปที่อยู่เบื้องหลังฉากเพื่อให้คุณจะเป็นที่O (n ^ 2).some()เมื่อใช้พวกเขาด้วย

การใช้การวนซ้ำ

 const compareArraysWithIncludes = (arr1, arr2) => {
     const [smallArray, bigArray] =
        arr1.length < arr2.length ? [arr1, arr2] : [arr2, arr1];

     for (let i = 0; i < smallArray.length; i++) {
       return bigArray.includes(smallArray[i]);
     }

      return false;
    };

ใช้. some ()

const compareArraysWithSome = (arr1, arr2) => {
  const [smallArray, bigArray] =
    arr1.length < arr2.length ? [arr1, arr2] : [arr2, arr1];
  return smallArray.some(c => bigArray.includes(c));
};

การใช้แผนที่ ความซับซ้อนของเวลา O (2n) => O (n)

const compararArraysUsingObjs = (arr1, arr2) => {
  const map = {};

  const [smallArray, bigArray] =
    arr1.length < arr2.length ? [arr1, arr2] : [arr2, arr1];

  for (let i = 0; i < smallArray.length; i++) {
    if (!map[smallArray[i]]) {
      map[smallArray[i]] = true;
    }
  }

  for (let i = 0; i < bigArray.length; i++) {
    if (map[bigArray[i]]) {
      return true;
    }
  }

  return false;
};

รหัสในของฉัน: stackblitz

ฉันไม่ใช่ผู้เชี่ยวชาญในการแสดงหรือ BigO ดังนั้นหากสิ่งที่ฉันพูดผิดนั้นให้ฉันรู้


3

สิ่งที่เกี่ยวกับการใช้การรวมกันของบาง / findIndex และ indexOf

ดังนั้นสิ่งนี้:

var array1 = ["apple","banana","orange"];
var array2 = ["grape", "pineapple"];

var found = array1.some(function(v) { return array2.indexOf(v) != -1; });

เพื่อให้สามารถอ่านได้มากขึ้นคุณสามารถเพิ่มฟังก์ชันนี้ในวัตถุ Array ได้

Array.prototype.indexOfAny = function (array) {
    return this.findIndex(function(v) { return array.indexOf(v) != -1; });
}

Array.prototype.containsAny = function (array) {
    return this.indexOfAny(array) != -1;
}

หมายเหตุ: หากคุณต้องการทำบางสิ่งด้วยเพรดิเคตคุณสามารถแทนที่ indexOf ภายในด้วย findIndex อื่นและเพรดิเคต


3

โซลูชันของฉันใช้Array.prototype.some ()และArray.prototype.includes ()ผู้ช่วยอาร์เรย์ซึ่งทำงานได้อย่างมีประสิทธิภาพเช่นกัน

ES6

const originalFruits = ["apple","banana","orange"];

const fruits1 = ["apple","banana","pineapple"];

const fruits2 = ["grape", "pineapple"];

const commonFruits = (myFruitsArr, otherFruitsArr) => {
  return myFruitsArr.some(fruit => otherFruitsArr.includes(fruit))
}
console.log(commonFruits(originalFruits, fruits1)) //returns true;
console.log(commonFruits(originalFruits, fruits2)) //returns false;


มีวิธีใดบ้างที่จะได้รับ index of include items จาก originalFruits?
Anzil khaN

3

ทางออกเดียวเพิ่มเติม

var a1 = [1, 2, 3, 4, 5]
var a2 = [2, 4]

ตรวจสอบว่า a1 มีองค์ประกอบทั้งหมดของ a2 หรือไม่

var result = a1.filter(e => a2.indexOf(e) !== -1).length === a2.length
console.log(result)

2

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

ลองสิ่งนี้:

function Check(A) {
    var myarr = ["apple", "banana", "orange"];
    var i, j;
    var totalmatches = 0;
    for (i = 0; i < myarr.length; i++) {
        for (j = 0; j < A.length; ++j) {
            if (myarr[i] == A[j]) {

                totalmatches++;

            }

        }
    }
    if (totalmatches > 0) {
        return true;
    } else {
        return false;
    }
}
var fruits1 = new Array("apple", "grape");
alert(Check(fruits1));

var fruits2 = new Array("apple", "banana", "pineapple");
alert(Check(fruits2));

var fruits3 = new Array("grape", "pineapple");
alert(Check(fruits3));

สาธิตที่ JSFIDDLE


2

ด้วยเครื่องหมายขีดล่าง

var a1 = [1,2,3];
var a2 = [1,2];

_.every(a1, function(e){ return _.include(a2, e); } ); //=> false
_.every(a2, function(e){ return _.include(a1, e); } ); //=> true

2
โดยส่วนตัวแม้ว่าฉันจะชอบขีดล่าง แต่นี่เป็นตัวอย่างคลาสสิกของวิธีการดูรหัสที่ซับซ้อน ไม่เพียง แต่ยากที่จะเข้าใจว่าเป็น underscorejs code แต่จากมุมมองการเข้ารหัสทั่วไปก็เป็นจริงเช่นเดียวกัน (เช่นคำว่า "ทุกคน" ไม่สปริงใจเมื่อฉันต้องการค้นหาดัชนีของบางสิ่งในอาร์เรย์ แต่ "indexOf" ทำ) เราควรหลีกเลี่ยงการใช้เครื่องมือของบุคคลที่สามโดยไม่จำเป็นเมื่อมีความยาวเพิ่มขึ้นไม่กี่ตัวอักษรอาจมีโซลูชัน JavaScript ที่แท้จริง ใช้ underscorejs เพื่อประโยชน์ของมันหมายความว่าโซลูชั่นของคุณจะแน่นคู่กับรหัสของบุคคลที่สาม
csharpforevermore

@csharpforever ยิ่งไปกว่านั้นฉันคิดว่านี่เป็นเรื่องของรสนิยมคุณบอกว่าวิธีนี้มีความซับซ้อนมากกว่าคนอื่น ๆ ที่ใช้indexOfฉันคิดว่าตรงกันข้าม :) ในมืออื่น ๆ ที่ผมเห็นในความพยายามที่จะไม่เพิ่มห้องสมุดภายนอกถ้าพวกเขาไม่จำเป็นต้องใช้จริงๆ แต่ฉันไม่ครอบงำจริงๆกับที่สามห้องสมุดส่วนที่ไม่เพียง แต่มีฟังก์ชันที่มีประโยชน์ แต่ยังแข็งฟังก์ชัน ตัวอย่างเช่น: คุณทดสอบทุกกรณีและเบราว์เซอร์นายกเทศมนตรีด้วยโซลูชันของคุณหรือไม่ .. ( everyไม่ได้พยายามค้นหาดัชนีในรายการ แต่ประเมินบางอย่างในทุกองค์ประกอบในรายการ)
fguillen

2

การเพิ่มไปยัง Array Prototype

คำเตือน:หลายคนจะแนะนำอย่างยิ่งต่อเรื่องนี้ ครั้งเดียวที่มันจะเป็นปัญหาจริงๆคือถ้าห้องสมุดเพิ่มฟังก์ชั่นต้นแบบที่มีชื่อเดียวกัน

รหัส:

Array.prototype.containsAny = function(arr) {
    return this.some(
        (v) => (arr.indexOf(v) >= 0)
    )
}

โดยไม่ใช้ฟังก์ชั่นลูกศรขนาดใหญ่:

Array.prototype.containsAny = function(arr) {
    return this.some(function (v) {
        return arr.indexOf(v) >= 0
    })
}

การใช้

var a = ["a","b"]

console.log(a.containsAny(["b","z"]))    // Outputs true

console.log(a.containsAny(["z"]))    // Outputs false

2

Vanilla JS ที่มีการจับคู่ & ตัวพิมพ์เล็กและตัวพิมพ์เล็ก

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

function search(arrayToSearch, wordsToSearch) {
    arrayToSearch.filter(v => 
        wordsToSearch.every(w => 
            v.toLowerCase().split(" ").
                reduce((isIn, h) => isIn || String(h).indexOf(w) >= 0, false)
            )
        )
}
//Usage
var myArray = ["Attach tag", "Attaching tags", "Blah blah blah"];
var searchText = "Tag attach";
var searchArr = searchText.toLowerCase().split(" "); //["tag", "attach"]

var matches = search(myArray, searchArr);
//Will return
//["Attach tag", "Attaching tags"]

สิ่งนี้มีประโยชน์เมื่อคุณต้องการให้ช่องค้นหาที่ผู้ใช้พิมพ์คำและผลลัพธ์สามารถมีคำเหล่านั้นในลำดับตำแหน่งและกรณีใด ๆ


2

อัปเดตคำตอบ @ Paul Grimshaw ใช้includesinsteed ofindexOfเพื่อให้อ่านได้มากขึ้น

let found = arr1.some (r => arr2.indexOf (r)> = 0)
let found = arr1.some (r => arr2.includes (r))


1

ฉันมากับวิธีแก้ปัญหาในโหนดใช้ขีดล่าง js เช่นนี้

var checkRole = _.intersection(['A','B'], ['A','B','C']);
if(!_.isEmpty(checkRole)) { 
     next();
}

0

ส่วนตัวผมจะใช้ฟังก์ชั่นต่อไปนี้:

var arrayContains = function(array, toMatch) {
    var arrayAsString = array.toString();
    return (arrayAsString.indexOf(','+toMatch+',') >-1);
}

วิธีการ "toString ()" จะใช้เครื่องหมายจุลภาคเพื่อคั่นค่าเสมอ จะใช้ได้กับประเภทดั้งเดิมเท่านั้น


2
สิ่งนี้จะไม่ทำงานเมื่อองค์ประกอบอยู่ที่จุดเริ่มต้นหรือตอนท้ายของอาร์เรย์หรือตามลำดับที่แตกต่างกัน
DanielM

1
-1 เพราะอย่างที่ DanielM บอกว่ามันพัง คุณสามารถเพิ่มและผนวกเครื่องหมายจุลภาคต่ออาร์เรย์ AsString เป็นวิธีแก้ปัญหา แต่จริงๆแล้วดูเหมือนว่ามันเป็นวิธีการแก้ปัญหาที่ซับซ้อนมากเกินไปในการใช้สตริง
JHH

0

Array .filter () ที่มีการเรียกซ้อนไปที่. find () จะส่งคืนองค์ประกอบทั้งหมดในอาร์เรย์แรกที่เป็นสมาชิกของอาร์เรย์ที่สอง ตรวจสอบความยาวของอาร์เรย์ที่ส่งคืนเพื่อตรวจสอบว่ามีอาร์เรย์ที่สองอยู่ในอาร์เรย์แรกหรือไม่

getCommonItems(firstArray, secondArray) {
  return firstArray.filter((firstArrayItem) => {
    return secondArray.find((secondArrayItem) => {
      return firstArrayItem === secondArrayItem;
    });
  });
}

มีวิธีการ "ล้าง" อาร์เรย์หรือไม่ เช่นเดียวกับการลบค่าในแถวที่สองหากมีอยู่ในแถวแรก?
sandrooco

0
console.log("searching Array: "+finding_array);
console.log("searching in:"+reference_array);
var check_match_counter = 0;
for (var j = finding_array.length - 1; j >= 0; j--) 
{
    if(reference_array.indexOf(finding_array[j]) > 0)
    {
        check_match_counter = check_match_counter + 1;
    }
}
 var match = (check_match_counter > 0) ? true : false;
console.log("Final result:"+match);

0
var target = ["apple","banana","orange"];
var checkArray = ["apple","banana","pineapple"];

var containsOneCommonItem = target.some(x => checkArray.some(y => y === x));`

["apple","grape"] //returns true;

["apple","banana","pineapple"] //returns true;

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