【问题标题】:Delete object returned by a function删除函数返回的对象
【发布时间】:2019-05-13 17:54:34
【问题描述】:

假设我有一个这样的对象

var $obj = {
    0 : {
        'id' : 3,
        'label' : 'Item One'
    },
    1 : {
        'id' : 7,
        'label' : 'Item Two'
    }
}

还有这样的功能:

function findById(obj, id){
    var result = false;
    $.each(obj, function(index, element){
        if(element.id === id)
        {
            result = element;
            return false;//stops $.each iteration
        }
    })
    return result;
}

现在,假设我想以编程方式删除 id 为“7”的项目,就像通过点击触发一样,无论如何我都会像这样触发我的函数:

delete findById($obj, 7);

在此“删除”之后,键为 1 且 id=7 的属性仍然存在。 我知道我错过了一些东西,但我无法摆脱这个 xD。 我应该如何从原始对象中删除该属性?我确定是关于范围的东西,或者无论如何在 javascript 中非常基本,我仍然无法理解。但是我继续遇到这样的问题,找不到这个问题的完整答案。

提前感谢任何可以帮助我的人;)

【问题讨论】:

  • 您正在删除结果,由函数调用返回,但对象的字段。

标签: javascript jquery object


【解决方案1】:

当您使用 $.each 迭代对象时,您所指的 index 实际上是对象键。

由于您的 findById() 不返回该密钥,您可能需要单独的删除方法

var $obj = {
    0 : {
        'id' : 3,
        'label' : 'Item One'
    },
    1 : {
        'id' : 7,
        'label' : 'Item Two'
    }
}

function deleteById(obj, id){    
    $.each(obj, function(key, element){
        if(element.id === id) {
           delete obj[key]
           return false;//stops $.each iteration
        }
    });   
}

deleteById($obj, 7)

console.log($obj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

【讨论】:

  • 这将是我当前设置的一个选项。有没有更简单的?我想知道为什么我可以编辑返回对象的属性(如编辑标签),但不能动态删除它
  • 因为您正在返回子对象但没有引用它的父对象。使用对象数组而不是单个对象也可能更简单。使用数组方法可以轻松find() 或获取数组中对象的索引
【解决方案2】:

如果我理解正确的话,你是想从原始对象中删除与选中项匹配的属性,对吧?

function findById(obj, id){
    var result = false;
    $.each(obj, function(index, element){
    
        // here the index is the name of the property on the original item. So "A", "B" etc.
        console.dir(index);
        if(element.id === id)
        {
            // you will need to know the name of the property you want to delete, not its value.
            result = index;
            return false;//stops $.each iteration
        }
    })
    return result;
}

var $obj = {
    "A" : {
        'id' : 3,
        'label' : 'Item One'
    },
    "B" : {
        'id' : 7,
        'label' : 'Item Two'
    }
}

// first you get the property name.
var propertyName = findById($obj, 7);
console.dir("Property to delete is: "+ propertyName);

console.dir("Original object before property deletion:");
console.dir($obj);
delete $obj[propertyName];
console.dir("Original object after property deletion:");
console.dir($obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

一些解释:
delete 执行从 JavaScript 对象 (reference) 中删除属性。
您的原始对象有两个属性,“A”和“B”。您想从对象中删除项目“B” - 在 JavaScript 中,这意味着从对象中删除属性。
因此,您需要做的是将要删除的属性的引用传递给 delete 方法:这就是为什么我更改了 findById 函数以返回元素的“索引”(又名名称)而不是其实际值.
最后一条指令delete $obj[propertyName];利用了JavaScript中的属性名称也可以用作对象的索引器这一事实。因此,在这种特定情况下,该行可以看作等同于delete $obj.B

【讨论】:

  • 真实对象比我在示例中展示的更复杂,我有 3 个嵌套级别,具有唯一 ID 但不是唯一索引。所以不幸的是,这不是我当前设置的选项...:\
  • 类似这样的 var $obj = { 0 : { 'id' : 3, 'label' : 'Item One', 'children': { 0 : { 'id' : 5, 'label ' : '项目二', 'children': { 0 : { 'id' : 13, 'label' : '项目三' } } }, 1 : { 'id' : 9, 'label' : '项目四' } } }, 1 : { 'id' : 7, 'label' : '第五项' } }
  • @MichelePazzi 将尝试对其进行修改以满足您的要求,但现在我不能保证什么。请给我一些时间。
  • 无论如何谢谢你,现在我正在使用另一个函数删除。但是任何更简单的方法都是受欢迎的;)
【解决方案3】:

在我看来,最简单的“one liner”解决方案是返回索引。它会给你一些好处

  1. 您无需创建新函数
  2. 您的旧功能不会失去其功能

然后你可以通过返回的索引删除对象。

请查看我的snippet,如果有什么我可以帮助改进我的答案,请发表评论。

祝你有美好的一天..

var $obj = {
    0 : {
        'id' : 3,
        'label' : 'Item One'
    },
    1 : {
        'id' : 7,
        'label' : 'Item Two'
    }
}

function findById(obj, id){
    var result = false;
    $.each(obj, function(index, element){
        if(element.id === id)
        {
            result = element;
            
            //return the index
            result.index = index;
            
            return false;//stops $.each iteration
        }
    })
    return result;
}

//delete object by index
delete $obj[findById($obj, 7).index]


console.log($obj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

【讨论】:

  • 真实对象比我在示例中展示的更复杂,我有 3 个嵌套级别,具有唯一 ID 但不是唯一索引。所以不幸的是,这不是我当前设置的选项...:\
  • 你能给我举个你更复杂的对象的例子吗?我在我的项目中做了类似的解决方案,我需要删除特定的深层嵌套对象。但以防万一,请分享复杂的 obj 示例,以便我改进我的答案..
  • var $obj = { 0 : { 'id' : 3, 'label' : 'Item One', 'children': { 0 : { 'id' : 5, 'label' : '项目二','孩子':{0:{'id':13,'标签':'项目三'}}},1:{'id':9,'标签':'项目四'}}} , 1 : { 'id' : 7, 'label' : '项目五' } }
  • 我打算使用索引/数字键进行排序,顺便说一下,我的实际 findById 函数也是递归的,可以在孩子中找到 id
【解决方案4】:

如果你有一个对象数组而不是一个集合,你可以使用filter 函数

var $obj = [
   {
      'id' : 3,
      'label' : 'Item One'
   },
   {
      'id' : 7,
      'label' : 'Item Two'
    }
];

function deleteElementByID($obj, id){
  return $obj.filter(function(item){
    return item.id != id;
  });
}

如果你不能或不想将其转换为数组,那么你可以使用 jQuery 的 map 函数:

function deleteElementByID(id){
  $obj = $.map($obj,function(item,index){
    if(item.id != id) return item;
  });
}

【讨论】:

  • 谢谢,我现在正在使用另一个功能删除,现在可以使用;)
  • 很公平,您是否尝试过上述解决方案?他们工作了吗?
猜你喜欢
  • 1970-01-01
  • 2020-04-23
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
  • 2015-07-05
  • 2018-03-02
  • 2012-02-29
  • 1970-01-01
相关资源
最近更新 更多