简体   繁体   English

检查 object 值是否存在于 Javascript 对象数组中,如果不存在,则将新的 object 添加到数组中

[英]Check if object value exists within a Javascript array of objects and if not add a new object to array

If I have the following array of objects:如果我有以下对象数组:

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

Is there a way to loop through the array to check whether a particular username value already exists and if it does do nothing, but if it doesn't to add a new object to the array with said username (and new ID)?有没有一种方法可以遍历数组以检查特定的用户名值是否已经存在,如果它什么都不做,但是如果它没有将新的 object 添加到具有所述用户名(和新 ID)的数组中?

Thanks!谢谢!

I've assumed that id s are meant to be unique here.我假设id在这里是唯一的。 some is a great function for checking the existence of things in arrays: 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'));

This small snippets works for me..这个小片段对我有用..

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

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

console.log(arrayOfObject.some(checkUsername))

if you have array of elements like ['john','marsh'] then we can do some thing like this如果你有像['john','marsh']这样的元素数组,那么我们可以做这样的事情

const checkUsername = element => element == 'john';
    
console.log(arrayOfObject.some(checkUsername))

It's rather trivial to check for existing username:检查现有用户名相当简单:

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

But it's not so obvious what to do when you have to add a new user to this array.但是当你必须向这个数组中添加一个新用户时,要做什么就不是那么明显了。 The easiest way out - just pushing a new element with id equal to array.length + 1 :最简单的方法 - 只需推送一个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

It will guarantee the IDs uniqueness, but will make this array look a bit strange if some elements will be taken off its end.它将保证 ID 的唯一性,但如果将某些元素从其末端移除,则会使该数组看起来有点奇怪。

This is what I did in addition to @sagar-gavhane 's answer除了@sagar-gavhane的回答之外,这就是我所做的

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

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

There could be MULTIPLE POSSIBLE WAYS to check if an element(in your case its Object) is present in an array or not.可能有多种可能的方法来检查一个元素(在你的情况下是它的对象)是否存在于数组中。

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

let say you want to find an object with id = 3.假设你想找到一个 id = 3 的对象。

1. find: It searches for an element in an array and if it finds out then it returns that element else return undefined. 1. find:它在数组中搜索一个元素,如果找到,则返回该元素,否则返回未定义。 It returns the value of the first element in the provided array that satisfies the provided testing function.它返回提供的数组中满足提供的测试功能的第一个元素的值。 reference 参考

const ObjIdToFind = 5;
const isObjectPresent = arr.find((o) => o.id === ObjIdToFind);
if (!isObjectPresent) {            // As find return object else undefined
  arr.push({ id: arr.length + 1, username: 'Lorem ipsum' });
}

2. filter: It searches for elements in an array and filters out all element that matches the condition. 2.过滤器:在数组中搜索元素,过滤掉所有符合条件的元素。 It returns a new array with all elements and if none matches the condition then an empty array.它返回一个包含所有元素的新数组,如果没有一个符合条件,则返回一个空数组。 reference 参考

const ObjIdToFind = 5;
const arrayWithFilterObjects= arr.filter((o) => o.id === ObjIdToFind);
if (!arrayWithFilterObjects.length) {       // As filter return new array
  arr.push({ id: arr.length + 1, username: 'Lorem ipsum' });
}

3. some: The some() method tests whether at least one element is present in an array that passes the test implemented by the provided function. 3. some: some() 方法测试数组中是否存在至少一个元素,该元素通过了提供的函数实现的测试。 It returns a Boolean value.它返回一个布尔值。 reference 参考

const ObjIdToFind = 5;
const isElementPresent = arr.some((o) => o.id === ObjIdToFind);
if (!isElementPresent) {                  // As some return Boolean value
  arr.push({ id: arr.length + 1, username: 'Lorem ipsum' });
}

I think that, this is the shortest way of addressing this problem.我认为,这是解决这个问题的最短方法。 Here I have used ES6 arrow function with .filter to check the existence of newly adding username.这里我使用了 .filter 的 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);

Link to Fiddle链接到小提琴

Let's assume we have an array of objects and you want to check if value of name is defined like this,假设我们有一个对象数组,并且您想检查 name 的值是否是这样定义的,

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

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

try this尝试这个

first method using some第一种方法使用一些

  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)

second method using includes, map第二种方法使用包含,映射

   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)

The Best Practice is like this. 最佳实践是这样的。

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

I like Andy's answer, but the id isn't going to necessarily be unique, so here's what I came up with to create a unique ID also.我喜欢安迪的回答,但 id 不一定是唯一的,所以这也是我想出的创建唯一 ID 的方法。 Can be checked at jsfiddle too.也可以在jsfiddle检查。 Please note that arr.length + 1 may very well not guarantee a unique ID if anything had been removed previously.请注意,如果之前删除了任何内容, arr.length + 1很可能不能保证唯一的 ID。

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

You could prototype your array to make it more modular, try something like this您可以对阵列进行原型设计以使其更加模块化,尝试这样的事情

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

And you can use it as:您可以将其用作:

 yourArray.hasElement(yourArrayElement)

Accepted answer can also be written in following way using arrow function on .some接受的答案也可以使用 .some 上的箭头功能以下列方式编写

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

Here is an ES6 method chain using .map() and .includes() :这是一个使用.map().includes()的 ES6 方法链:

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. Map over existing users to create array of username strings.映射现有用户以创建用户名字符串数组。
  2. Check if that array of usernames includes the new username检查该用户名数组是否包含新用户名
  3. If it's not present, add the new user如果不存在,请添加新用户

i did try the above steps for some reason it seams not to be working for me but this was my final solution to my own problem just maybe helpful to any one reading this :由于某种原因,我确实尝试了上述步骤,但它似乎对我不起作用,但这是我对自己问题的最终解决方案,可能对任何阅读本文的人都有帮助:

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

here post.likes is an array of users who liked a post.这里的 post.likes 是一个喜欢帖子的用户数组。

This can be done fairly simply with a couple of array methods and in several different ways.这可以通过几个数组方法和几种不同的方式相当简单地完成。

1. Simply pushing the new object to the source array and ignoring the value returned by the function ( true , or the array's length when using .push() ) 1. 简单地将新对象推送到源数组并忽略函数返回的值( true ,或者使用.push()时数组的长度)

Below, I first map the array to a new shallow array of only the usernames and then check to see if that array .includes() the specified username.下面,我首先将数组映射到仅包含用户名的新浅数组,然后检查该数组.includes()是否为指定的用户名。 If it does, I return true by nature of the ||如果是这样,我会根据||的性质返回true operator.操作员。 Otherwise, I push a new object for the specified username back to the source array of objects.否则,我将指定用户名的新对象推送回源对象数组。

 const arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }]; const usernameCheck = (arr, usr) => arr.map(u => u.username).includes(usr) || arr.push({ id: arr.length+1, username: usr }); usernameCheck(arr, 'jeremy'); console.log(arr);

2. Returning the array rather than simply returning true , or the array's length when using .push() : 2. 返回数组而不是简单地返回true ,或者使用.push()时数组的长度:

This can also be improved in several ways if you would like more flexibility.如果您想要更大的灵活性,这也可以通过多种方式进行改进。 If you don't care to return true and would rather return the new array for immediate use, we can make use of the , operator by simply returning the array at the end of the function, whether or not a push was made.如果您不想返回true而是希望返回新数组以供立即使用,我们可以通过在函数末尾简单地返回数组来使用,运算符,无论是否进行了推送。 With this solution, the original array is still pushed to, and because we return the array, we can perform our console.log() directly on the function execution, rather than needing to run the function first, and then log the array's content.使用这个解决方案,原始数组仍然被推送到,并且由于我们返回数组,我们可以直接在函数执行时执行console.log() ,而不需要先运行函数,然后记录数组的内容。

 const arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }]; const usernameCheck = (arr, usr) => (arr.map(u => u.username).includes(usr) || arr.push({ id: arr.length+1, username: usr }), arr); console.log(usernameCheck(arr, 'jeremy'));

3. Using a shallow copy, not altering the source array: 3. 使用浅拷贝,不改变源数组:

If on the other hand, you only wanted to return a shallow copy of the new array without directly pushing to the source array, you could do so using the spread operator ... , or the .concat() method if you prefer:另一方面,如果您只想返回新数组的浅表副本而不直接推送到源数组,则可以使用扩展运算符... ,或者如果您愿意,可以使用.concat()方法:

 const arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }]; const usernameCheck = (arr, usr) => arr.map(u => u.username).includes(usr) ? [...arr] : [...arr, { id: arr.length+1, username: usr }]; console.log('This will return the array with the added username:\n\nusernameCheck(arr, \'jeremy\')', usernameCheck(arr, 'jeremy')); console.log('But the original array remains untouched:\n\narr', arr);

Native functions of array are sometimes 3X - 5X times slower than normal loops.数组的原生函数有时比普通循环慢 3X - 5X 倍。 Plus native functions wont work in all the browsers so there is a compatibility issues.加上本机功能无法在所有浏览器中运行,因此存在兼容性问题。

My Code:我的代码:

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

This way you can achieve result faster.这样您可以更快地获得结果。

Note: I have not checked if parameter passed is empty or not, if you want you can put a check on it or write a regular expression for particular validation.注意:我没有检查传递的参数是否为空,如果您愿意,可以对其进行检查或编写正则表达式以进行特定验证。

xorWith in Lodash can be used to achieve this xorWith中的 xorWith 可用于实现此目的

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

Check it here :在这里检查:

https://stackoverflow.com/a/53644664/1084987 https://stackoverflow.com/a/53644664/1084987

You can create something like if condition afterwards, like您可以在之后创建类似 if 条件的内容,例如

if(!contains(array, obj)) add();
function number_present_or_not() {
  var arr = [2, 5, 9, 67, 78, 8, 454, 4, 6, 79, 64, 688];
  var found = 6;
  var found_two;
  for (i = 0; i < arr.length; i++) {
    if (found == arr[i]) {
      found_two = arr[i];
      break;
    }
  }
  if (found_two == found) {
    console.log('number present in the array');
  } else {
    console.log('number not present in the array');
  }
}

You can try this also你也可以试试这个

 const addUser = (name) => {
    if (arr.filter(a => a.name == name).length <= 0)
        arr.push({
            id: arr.length + 1,
            name: name
        })
}
addUser('Fred')

If I have the following array of objects:如果我有以下对象数组:

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

Is there a way to loop through the array to check whether a particular username value already exists and if it does do nothing, but if it doesn't to add a new object to the array with said username (and new ID)?有没有一种方法可以遍历数组以检查特定的用户名值是否已经存在,并且不执行任何操作,但是是否不使用上述用户名(和新ID)将新对象添加到数组中?

Thanks!谢谢!

I was given a condition to check the data in the table of the mysql database the object array of my table consist of the id, latitude and longitude as column names, I have to check whether the location is in the database else insert this into the table so: I created a function of handle submit called by a button,我有一个条件来检查mysql数据库表中的数据我表的对象数组由id,纬度和经度作为列名组成,我必须检查位置是否在数据库中,否则将其插入表so:我创建了一个由按钮调用的句柄提交函数,

handle Submit = (event) => {
        const latitude = document.getElementById("latitude").innerHTML;
        const longitude = document.getElementById("longitude").innerHTML;
        const found = this.state.data.some((el) => el.latitude === latitude);
    if (!found) {
      Axios.post("http://localhost:3001/api/insert", {
        latitude: latitude,
        longitude: longitude,
      }).then(() => {
        alert("successful insert");
      });
      console.log(latitude, longitude);
    }
  };

Here you can see the conditional statement for inserting if not exist in the database.在这里您可以看到如果数据库中不存在插入的条件语句。

function containsObject(obj, list) {
    let exists = false;
    for (var i = 0; i < list.length; i++) {
       if (list[i].toString() == obj.toString()) {
          exists = true;
       }
    }

   return exists;
 }
const __checkIfElementExists__ = __itemFromArray__ => __itemFromArray__.*sameKey* === __outsideObject__.*samekey*;

    if (cartArray.some(checkIfElementExists)) {
        console.log('already exists');
    } else {
        alert('does not exists here')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM