检查Javascript对象数组中是否存在对象值,如果不存在,则向数组添加一个新对象。

283

如果我有以下的对象数组:

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

有没有一种方法可以遍历数组,检查特定的用户名值是否已经存在,如果存在,则什么也不做,但如果不存在,则添加一个带有该用户名(和新ID)的新对象到数组中?

谢谢!


1
比尔和泰德应该有相同的ID吗? - user2357112
为什么有两个具有相同 id 的元素?这个数组中的元素是否可能被移除,或者我们可以确定新元素的 id 总是等于 arr.length + 1 吗? - raina77ow
如果您不想使用循环,请查看这个 Q&A 来扩展数组原型,https://dev59.com/YXI-5IYBdhLWcg3wKVA9。 - Cem Özer
本地函数与普通循环相比较慢,而且它们的支持仅限于某些浏览器版本。请检查下面的答案。 - Zaheen
这是一个基本上错误的问题,因为你可以通过避免使用数组来实现。 - Bekim Bacaj
@user2576960 当你有时间时,请检查我的解决方案,因为它通过一个简单的一行函数来简洁地实现了这个目标。我提供了几种不同的方法来实现这个目标,但我觉得我的**#1#2**解决方案最符合你的要求。 - Brandon McConnell
22个回答

2

这是一个使用.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. 遍历现有用户,创建用户名字符串数组。
  2. 检查该用户名数组是否包含新用户名
  3. 如果不存在,则添加新用户

1
请看下面的示例。

$(document).ready(function(){
  const arr = document.querySelector(".list");
    var abcde = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' }];
  $("#btnCheckUser").click(function() {
    var tbUsername = $("#tbUsername").val();
    if (abcde.some(obj => obj.username === tbUsername)) {
        alert('existing user ' + tbUsername);
        return;
    }
    else {
        abcde.push({ id: abcde.length + 1, username: tbUsername });
        alert('added new user ' + tbUsername);
        arr.appendChild(createArray(tbUsername));
        return;
    }
  });
  
  function createArray(name) {
    let li = document.createElement("li");
    li.textContent = name;
    return li;
  }
  abcde.forEach((x) => arr.appendChild(createArray(x.username)));

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<p>Add text and click on Check.</p>

<input type="text" id="tbUsername" />
<button type="button" id="btnCheckUser">Check</button>

<div class="list">
  <ul></ul>
</div>


这并没有像问题所要求的那样将指定的用户名添加到源数组中。 - Brandon McConnell
我认为它按照问题中的要求将一个用户名添加到数组中。 - undefined
在提供的代码中,新条目在原始数组abcde中的哪里添加?arr.appendChild(createArray(tbUsername))处理的是NodeList,而不是Array,而且abcde.push从不再被调用以添加新的用户输入条目。 - undefined
代码中的原始数组是"abcde",UL用于片段用户方便测试代码并根据需要进行调整。 编辑:还显示了"abcde"数组。 - undefined
啊,好的,我现在明白了。谢谢你的解释! - undefined

1

在此大大简化了我之前的解决方案,并通过在检查指定ID的存在之前不必要地迭代整个数组来提供更好的性能。

这应该是最简单的解决方案(我认为):

const users = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];
const addUser = (username) => {
  const user = users.find((user) => user.username === username);
  if (user) return { ...user, new: false };
  const newUser = {
    id: users.length + 1,
    username,
  };
  users.push(newUser);
  return { ...newUser, new: true };
};

这是一个实时示例的展示:

const users = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];
const addUser = (username) => {
  const user = users.find((user) => user.username === username);
  if (user) return { ...user, new: false };
  const newUser = {
    id: users.length + 1,
    username,
  };
  users.push(newUser);
  return { ...newUser, new: true };
};

// a little extra scripting here to support the input and button in the example

const form = document.querySelector('form');
const input = document.querySelector('input');
const span = document.querySelector('span');
const pre = document.querySelector('pre');

const syncDataWithPre = () => {
  pre.innerHTML = JSON.stringify(users, null, 2);
};

form.onsubmit = (e) => {
  e.preventDefault();
  span.textContent = '';
  if (input.value) {
    const user = addUser(input.value);
    const { new: isNew, ...userDetails } = user;
    span.classList[isNew ? 'add' : 'remove']('new');
    span.textContent = `User ${isNew ? 'added' : 'already exists'}`;
  }
  input.value = '';
  syncDataWithPre();
};

syncDataWithPre();
body {
  font-family: arial, sans-serif;
}
span {
  display: block;
  padding-top: 8px;
  font-weight: 700;
  color: #777;
}
span:empty {
  display: none;
}
.new {
  color: #0a0;
}
.existing: {
  color: #777;
}
<form>
  <input placeholder="New username" />
  <button>Add user</button>
</form>
<span></span>
<pre></pre>


1
我喜欢Andy的答案,但是id不一定是唯一的,所以这是我想出来的创建唯一ID的方法。也可以在jsfiddle上检查。请注意,如果之前已经删除了任何内容,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 };
}

我喜欢其他答案中的简洁性,我只是发布了我的答案以添加唯一ID的检查。 - Uxonith
感谢您的回答,Uxonith。目前我不需要唯一标识符,因为我不会从数组中删除用户。如果需要,我会将此解决方案留在后备计划中。再次感谢。 - user2576960

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是一个喜欢该帖子的用户数组。


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

0

数组的本地函数有时比普通循环慢3倍到5倍。此外,本地函数在所有浏览器中都无法工作,因此存在兼容性问题。

我的代码:

<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

我被要求检查mysql数据库表中的数据条件,我的表对象数组由id、纬度和经度列名称组成,我必须检查位置是否在数据库中,否则将其插入到表中: 我创建了一个名为handleSubmit的函数,并通过按钮调用它。

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

在这里,您可以看到插入不存在于数据库中的条件语句。


0

Lodash中的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' } ]

0

你也可以试试这个

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接