ตรวจสอบว่ามีค่าวัตถุอยู่ในอาร์เรย์ Javascript ของวัตถุหรือไม่และไม่เพิ่มวัตถุใหม่ลงในอาร์เรย์


147

ถ้าฉันมีอาร์เรย์ของวัตถุต่อไปนี้:

[ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

มีวิธีวนลูปผ่านอาร์เรย์เพื่อตรวจสอบว่ามีค่าชื่อผู้ใช้เฉพาะอยู่แล้วหรือไม่และไม่ทำอะไรเลย แต่ถ้าไม่เพิ่มวัตถุใหม่ในอาร์เรย์ด้วยชื่อผู้ใช้ดังกล่าว (และ ID ใหม่)

ขอบคุณ!


1
Bill และ Ted ควรจะมีรหัสเดียวกันหรือไม่?
user2357112 รองรับโมนิก้า

ทำไมมีสององค์ประกอบด้วยเหมือนกันid? เป็นไปได้หรือไม่ว่าองค์ประกอบจะถูกลบออกจากอาร์เรย์นี้หรือเรามั่นใจได้ว่าองค์ประกอบใหม่จะมีidค่าเท่ากันarr.length + 1หรือไม่
raina77ow

หากคุณไม่ต้องการที่จะห่วงผ่านมันตรวจสอบ Q & A นี้สำหรับการขยายต้นแบบอาร์เรย์stackoverflow.com/questions/1988349/...
Cem Özer

ฟังก์ชั่นพื้นฐานจะช้าลงเมื่อเทียบกับลูปปกติและการสนับสนุนจะ จำกัด เฉพาะเบราว์เซอร์บางรุ่น ตรวจสอบคำตอบของฉันด้านล่าง
Zaheen

นี่เป็นคำถามที่ผิดพลาดเพราะคุณสามารถทำได้โดยหลีกเลี่ยงการใช้อาร์เรย์
Bekim Bacaj

คำตอบ:


234

ฉันสันนิษฐานว่าidมีความหมายที่จะไม่ซ้ำกันที่นี่ someเป็นฟังก์ชั่นที่ยอดเยี่ยมสำหรับการตรวจสอบการมีอยู่ของสิ่งต่าง ๆ ในอาร์เรย์:

const arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];

function add(arr, name) {
  const { length } = arr;
  const id = length + 1;
  const found = arr.some(el => el.username === name);
  if (!found) arr.push({ id, username: name });
  return arr;
}

console.log(add(arr, 'ted'));


1
ขอบคุณแอนดี้นี่เป็นวิธีแก้ปัญหาที่สะอาดมากและใช้งานได้ดีมาก ฉันไม่เคยเจอวิธีการบางอย่างมาก่อน สมมติฐานของคุณถูกต้องตัวอย่าง ID ของฉันเป็นเพียงการพิมพ์ผิดฉันใช้ arr.length + 1 เพื่อกำหนด ID
2576960

3
ระวังว่า IE8 และก่อนหน้านี้ไม่รองรับฟังก์ชั่นบางอย่าง
BetaRide

ฟังก์ชั่นที่พบสามารถทำเป็น IF ได้ไหม สิ่งที่ชอบ: ถ้า (arr.some (ฟังก์ชั่น (เอ) {el.Id == someId) และมันจะกลับมาจริงหรือเท็จถ้ามีอยู่หรือไม่?
stibay

@stibay, some ไม่กลับแบบบูล foundจะเป็นtrueหรือfalseขึ้นอยู่กับเงื่อนไขในการติดต่อกลับ
Andy

1
อ๋อแน่นอน: if (arr.some(function (el) { return el.Id == someId; })) { // do something }. อย่าลืมสิ่งนั้นreturnหรือคุณจะไม่ได้อะไรคืน
แอนดี้

26

มันค่อนข้างจะตรวจสอบชื่อผู้ใช้ที่มีอยู่:

var arr = [{ id: 1, username: 'fred' }, 
  { id: 2, username: 'bill'}, 
  { id: 3, username: 'ted' }];

function userExists(username) {
  return arr.some(function(el) {
    return el.username === username;
  }); 
}

console.log(userExists('fred')); // true
console.log(userExists('bred')); // false

แต่ไม่ชัดเจนว่าจะทำอย่างไรเมื่อคุณต้องเพิ่มผู้ใช้ใหม่ในอาร์เรย์นี้ วิธีที่ง่ายที่สุด - เพียงแค่ผลักองค์ประกอบใหม่ที่มีidค่าเท่ากับarray.length + 1:

function addUser(username) {
  if (userExists(username)) {
    return false; 
  }
  arr.push({ id: arr.length + 1, username: username });
  return true;
}

addUser('fred'); // false
addUser('bred'); // true, user `bred` added

มันจะรับประกันเอกลักษณ์ ID แต่จะทำให้อาร์เรย์นี้ดูแปลก ๆ ถ้าองค์ประกอบบางอย่างจะถูกนำออกไปจากจุดสิ้นสุด


ขอบคุณสำหรับสิ่งนี้. ฉันไปกับทางออกของ Andy ในที่สุดเพราะมันเป็นวิธีที่สั้นกว่าในการบรรลุสิ่งเดียวกัน ฉันจะไม่ลบผู้ใช้ไม่ว่าในกรณีใด ๆ ดังนั้นรหัสควรจะคงที่ การตรวจสอบช่วยให้ผู้ใช้เข้าสู่ระบบออกและกลับมาอีกครั้งโดยไม่ต้องอาร์เรย์ทำงานล่วงเวลา สำหรับข้อมูลฉันใช้ฟังก์ชันนี้ร่วมกับ passport.js และฉันไม่สามารถหาวิธีลบผู้ใช้ออกจากอาร์เรย์ได้โดยไม่ต้องเล่นกับรหัสหนังสือเดินทาง วิธีนี้ใช้ได้ผลดี
2576960

18

ตัวอย่างเล็ก ๆ นี้เหมาะกับฉัน ..

const arrayOfObject = [{ id: 1, name: 'john' }, {id: 2, name: 'max'}];

const checkUsername = obj => obj.name === 'max';

console.log(arrayOfObject.some(checkUsername))

1
วิธีการที่สง่างาม! - รายละเอียดเพิ่มเติมและตัวอย่างการใช้งาน.someพบได้ที่นี่ - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
James Marino

10

ฉันคิดว่านี่เป็นวิธีที่สั้นที่สุดในการจัดการปัญหานี้ ที่นี่ฉันได้ใช้ฟังก์ชันลูกศร ES6 กับ. ตัวกรองเพื่อตรวจสอบการมีอยู่ของชื่อผู้ใช้ที่เพิ่มใหม่

var arr = [{
    id: 1,
    username: 'fred'
}, {
    id: 2,
    username: 'bill'
}, {
    id: 3,
    username: 'ted'
}];

function add(name) {
    var id = arr.length + 1;        
            if (arr.filter(item=> item.username == name).length == 0){
            arr.push({ id: id, username: name });
        }
}

add('ted');
console.log(arr);

เชื่อมโยงไปยังซอ


3

นี่คือสิ่งที่ฉันทำนอกจากคำตอบของ@ sagar-gavhane

const newUser = {_id: 4, name: 'Adam'}
const users = [{_id: 1, name: 'Fred'}, {_id: 2, name: 'Ted'}, {_id: 3, 'Bill'}]

const userExists = users.some(user => user.name = newUser.name);
if(userExists) {
    return new Error({error:'User exists'})
}
users.push(newUser)

สวัสดีถ้าฉันพบมูลค่าฉันจะเข้าถึงรหัสได้อย่างไร
Kusal Kithmal

มันง่ายมากที่จะทำอย่างนั้น... if(userExists) { const userId = userExists.id return userId; } ...
Michael Enitan

2

คำตอบที่ยอมรับยังสามารถเขียนได้ในวิธีต่อไปนี้โดยใช้ฟังก์ชั่นลูกศรบน. บางส่วน

 function checkAndAdd(name) {
     var id = arr.length + 1;
     var found = arr.some((el) => {
           return el.username === name;
     });
     if (!found) { arr.push({ id: id, username: name }); }
 }

2

นี่คือเชนเมธอด ES6 ที่ใช้.map()และ.includes():

const arr = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

const checkForUser = (newUsername) => {
      arr.map(user => {
        return user.username
      }).includes(newUsername)
    }

if (!checkForUser('fred')){
  // add fred
}
  1. แม็พกับผู้ใช้ที่มีอยู่เพื่อสร้างอาร์เรย์ของสตริงชื่อผู้ใช้
  2. ตรวจสอบว่าชื่อผู้ใช้นั้นมีชื่อผู้ใช้ใหม่หรือไม่
  3. หากไม่มีอยู่ให้เพิ่มผู้ใช้ใหม่

1

ฉันชอบคำตอบของแอนดี้ แต่รหัสไม่จำเป็นต้องเป็นเอกลักษณ์ดังนั้นนี่คือสิ่งที่ฉันคิดขึ้นมาเพื่อสร้างรหัสเฉพาะด้วย สามารถตรวจสอบได้ที่jsfiddleด้วย โปรดทราบว่าarr.length + 1อาจไม่รับประกันรหัสที่ไม่ซ้ำกันหากมีสิ่งใดที่ถูกลบไปก่อนหน้านี้

var array = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' } ];
var usedname = 'bill';
var newname = 'sam';

// don't add used name
console.log('before usedname: ' + JSON.stringify(array));
tryAdd(usedname, array);
console.log('before newname: ' + JSON.stringify(array));
tryAdd(newname, array);
console.log('after newname: ' + JSON.stringify(array));

function tryAdd(name, array) {
    var found = false;
    var i = 0;
    var maxId = 1;
    for (i in array) {
        // Check max id
        if (maxId <= array[i].id)
            maxId = array[i].id + 1;

        // Don't need to add if we find it
        if (array[i].username === name)
            found = true;
    }

    if (!found)
        array[++i] = { id: maxId, username: name };
}

ฉันชอบความเรียบง่ายในคำตอบอื่น ๆ ฉันเพิ่งโพสต์ของฉันเพื่อเพิ่มการตรวจสอบ ID ที่ไม่ซ้ำ
Uxonith

ขอบคุณสำหรับคำตอบของคุณ Uxonith ในตอนนี้ฉันไม่จำเป็นต้องมี ID เฉพาะเพราะฉันจะไม่ลบผู้ใช้ออกจากอาร์เรย์ ฉันจะเก็บความละเอียดนี้ไว้ในกระเป๋าหลังของฉันในกรณีที่มีความจำเป็นเกิดขึ้น ขอขอบคุณอีกครั้ง
user2576960

1

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

    Array.prototype.hasElement = function(element) {
        var i;
        for (i = 0; i < this.length; i++) {
            if (this[i] === element) {
                return i; //Returns element position, so it exists
            }
        }

        return -1; //The element isn't in your array
    };

และคุณสามารถใช้มันเป็น:

 yourArray.hasElement(yourArrayElement)

1

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

let pst = post.likes.some( (like) => {  //console.log(like.user, req.user.id);
                                     if(like.user.toString() === req.user.id.toString()){
                                         return true
                                     } } )

นี่ post.likes เป็นอาร์เรย์ของผู้ใช้ที่ชอบโพสต์


1

ลองนี้

วิธีแรกที่ใช้บางอย่าง

  let arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];
    let found = arr.some(ele => ele.username === 'bill');
    console.log(found)

วิธีที่สองใช้รวมถึงแผนที่

   let arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];
    let mapped = arr.map(ele => ele.username);
    let found = mapped.includes('bill');
    console.log(found)

ถ้าฉันต้องการเปรียบเทียบวัตถุที่มี 2 คุณลักษณะเช่น {"name": "test1", "age": 30}
probitaille

1

สมมติว่าเรามีอาร์เรย์ของวัตถุและคุณต้องการตรวจสอบว่ามูลค่าของชื่อมีการกำหนดเช่นนี้หรือไม่

let persons = [ {"name" : "test1"},{"name": "test2"}];

if(persons.some(person => person.name == 'test1')) {
    ... here your code in case person.name is defined and available
}

โปรดเพิ่มประโยคสองสามประโยคเพื่ออธิบายว่าโค้ดของคุณทำอะไรอยู่เพื่อให้คุณสามารถรับ upvotes เพิ่มเติมสำหรับคำตอบของคุณ
วิเคราะห์ฟัซซี

จะเป็นอย่างไรถ้าฉันต้องการเปรียบเทียบวัตถุกับ 2 แอตทริบิวต์เช่น {"name": "test1", "age": 30}
probitaille

0

ฟังก์ชั่นพื้นฐานของอาเรย์บางครั้ง 3X - 5X ช้ากว่าลูปปกติ ฟังก์ชั่นแบบเนทีฟจะไม่ทำงานในเบราว์เซอร์ทั้งหมดดังนั้นจึงมีปัญหาความเข้ากันได้

รหัสของฉัน:

<script>
  var obj = [];

  function checkName(name) {
    // declarations
    var flag = 0;
    var len = obj.length;   
    var i = 0;
    var id = 1;

    // looping array
    for (i; i < len; i++) {
        // if name matches
        if (name == obj[i]['username']) {
            flag = 1;
            break;
        } else {
            // increment the id by 1
            id = id + 1;
        }
    }

    // if flag = 1 then name exits else push in array
    if (flag == 0) {
      // new entry push in array        
      obj.push({'id':id, 'username': name});
    }
  }
  // function end

  checkName('abc');
</script>

วิธีนี้คุณสามารถบรรลุผลได้เร็วขึ้น

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


0

xorWith ใน Lodash สามารถใช้เพื่อให้บรรลุเป้าหมายนี้ได้

let objects = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]
let existingObject = { id: 1, username: 'fred' };
let newObject = { id: 1729, username: 'Ramanujan' }

_.xorWith(objects, [existingObject], _.isEqual)
// returns [ { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

_.xorWith(objects, [newObject], _.isEqual)
// returns [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ,{ id: 1729, username: 'Ramanujan' } ]


0

ฟังก์ชัน number_present_or_not () { var arr = [ 2,5,9,67,78,8,454,4,6,79,64,688 ] ; var found = 6; var found_two; สำหรับ (i = 0; i

    }
    if ( found_two == found )
    {
        console.log("number present in the array");
    }
    else
    {
        console.log("number not present in the array");
    }
}

-1

แนวปฏิบัติที่ดีที่สุดเป็นเช่นนี้

var arr = ["a","b","c","d"];
console.log(arr.includes("a")); //---- true;
console.log(arr.includes("k")); //---- false;
console.log(arr.includes("c")); //---- true;

18
คำถามเกี่ยวกับอาร์เรย์ของวัตถุและสิ่งนี้จะไม่ทำงาน
Adrian Enriquez

นี่ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถาม
Ahsan Mukhtar

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