在Javascript对象数组中查找并删除第一个匹配的元素

19
假设我有一个数组:
    members = [
        {name: 'Anna', class: 'one'}, 
        {name: 'Bob', class: 'two'},  
        {name: 'Chuck', class: 'two'}];

    removed = members.myRemoveByClass('two');     //something like

    // removed is {name: 'Bob', class: 'two'} 
    // members is [{name: 'Anna', class: 'one'}, {name: 'Chuck', class: 'two'}]

我正在寻找适用于myRemoveByClass的东西。ES2015或使用Lodash都可以。数组已经被排序过了。没有我所看到问题完全符合我所寻找的。


2
该问题似乎没有任何尝试来解决问题。StackOverflow希望您首先尝试解决自己的问题,因为您的尝试可以帮助我们更好地理解您的需求。请编辑问题以展示您所尝试的内容,以便说明您遇到了一个具体的障碍[MCVE]。如需更多信息,请参见[ask]并进行[tour]。 - CertainPerformance
1
你能指出哪里说我们需要展示尝试了什么吗?我应该把我在这个问题上花费的时间或者所有没有解决我提出的问题的SO解决方案链接放在哪里呢?例如:https://dev59.com/2F8e5IYBdhLWcg3wdqKT https://dev59.com/eGkv5IYBdhLWcg3wpCQz https://dev59.com/LFsW5IYBdhLWcg3wTly8 等等。在这里展示我的努力并不能澄清问题。 - Gazzer
在这里付出努力并不能澄清问题。这将有助于说明这不是一个没有努力的作业倾倒或从头开始编写代码的问题,这些都是被反对的 - 请参见我上面评论中的前两个链接。搜索现有的问题以获取所需功能的代码与自己尝试编写代码并不相同。 - CertainPerformance
1
@CertainPerformance “这将有助于说明这不是一个没有努力的作业倾倒或从头开始写我的代码问题。” 这不就是声望的全部意义吗?“并不意味着要尝试自己编写代码” 为什么你会认为我没有花几个小时尝试自己编写代码,而我确实尝试了,并发现我的代码对构建问题没有帮助? - Gazzer
8个回答

19
你可以使用 Array.prototype.findIndex()

findIndex() 方法返回数组中满足所提供测试函数的第一个元素的索引。否则,它返回 -1,表示没有元素通过测试。

然后通过该 index splice() 对对象进行操作。

let members = [
        {name: 'Anna', class: 'one'}, 
        {name: 'Bob', class: 'two'},  
        {name: 'Chuck', class: 'two'}];
let idx = members.findIndex(p => p.class=="two");
if(idx >= 0){ //check if item found
  var removed = members.splice(idx, 1);     
  console.log(removed);
  console.log(members);
}
else{ //or not
  console.log('Not found!');
}


4
这是非常错误的 - 如果没有找到元素,idx 将会是 -1,然后 members.splice(idx, 1) 将会删除 members 的最后一个元素,这 不是 在这种情况下想要的结果... - Max

7
您可以创建自己的数组类:
 class Members extends Array {
   removeByClass(className) {
     for(const [index, member] of this.entries())
        if(member.class === className) 
           return this.splice(index, 1)[0];
   }
}

将其用作

 const members = new Members([ {/*...*/}, {/*...*/} ]);
 members.removeByClass("...");

注意:"class"是一个非常糟糕的名称,因为它是一个保留关键字


我本来想改掉它,但是ESLint似乎并不在意那里的“class”,所以我把它留下了!我现在不想编辑它,这样解决方案就能与问题匹配! - Gazzer

2
您可以找到第一次出现的索引并检查此索引,然后从数组中截取该对象。

var members = [{ name: 'Anna', class: 'one' }, { name: 'Bob', class: 'two' }, { name: 'Chuck', class: 'two' }],
    index = members.findIndex(o => o.class === 'two'),
    removed = index !== -1 && members.splice(index, 1);

console.log(removed);
console.log(members);
.as-console-wrapper { max-height: 100% !important; top: 0; }


2
你可以使用 Array.prototype.find() 结合 Array.prototype.splice()
代码示例:

const members = [{ name: 'Anna', class: 'one' }, { name: 'Bob', class: 'two' }, { name: 'Chuck', class: 'two' }]

const removeFirstMatchByClass = (members, className) => {
  const index = members.findIndex(member => member.class === className)
  return index !== -1 ? [...members.slice(0, index), ...members.slice(index + 1)] : [...members]
}

console.log(removeFirstMatchByClass(members, 'two'))


2
这也可以起作用。
removeByClass(array, filterString) {
   const memberToRemove = array.find(element => {
     return element.class === filterString;
   });
   array.splice(array.indexOf(memberToRemove), 1);
 }

 let members = [
  { name: 'Anna', class: 'one' },
  { name: 'Bob', class: 'two' },
  { name: 'Chuck', class: 'two' }];

this.removeByClass(members, 'two');

1

你可以使用some方法来查找需要移除的成员,并返回true以停止循环。

let members = [
  {name: 'Anna', class: 'one'}, 
  {name: 'Bob', class: 'two'},  
  {name: 'Chuck', class: 'two'}
];

function myRemoveByClass(members, className) {
  let foundMember = null;
  members.some((member, index) => {
    if (member.class == className) {
      members.splice(index, 1);
      foundMember = member;
      return true;
    }
  });
  
  return foundMember;
}

let removed = myRemoveByClass(members, 'two');
console.log(removed);
console.log(members);

正如 Jonas 在这里指出的那样,你应该避免使用 class,因为它是一个保留字。

1
简单来说:
function removeByClass(obj, prop) {
    for (let i = 0; i < obj.length; i++) {
        if (obj[i].class == prop) obj.splice(i, 1);
    }   
}

1
您可以使用 withoutfindWhere
var arr = _.without(members , _.findWhere(members , {
 class: "two"
}));

4
这需要使用 Lodash 吗?看起来这是 Lodash 语法。 - Moshe

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