【问题标题】:Find object in array and then edit it在数组中查找对象然后编辑它
【发布时间】:2015-07-04 05:53:29
【问题描述】:

假设我有以下数组:

var things = [
    {
        id: "12345",
        name: "Bryan"
    },
    {
        id: "55555",
        name: "Justin"
    }
]

我想搜索 id55555 的对象。但我想将该特定对象的名称更新为 Justin 的“Mike”,但仍保持整个军队完好无损。

目前,我想出了一种搜索对象的方法,但我找不到实际编辑该特定结果的解决方案。

谁能帮帮我?这是我目前所拥有的:

var thing = things.filter(function (item) {
    return "55555" === item.id;
})[0]

【问题讨论】:

标签: javascript jquery


【解决方案1】:

找到正确的 ID 并更改名称的函数怎么样

var things = [
    {
        id: "12345",
        name: "Bryan"
    },
    {
        id: "55555",
        name: "Justin"
    }
]

function updateThings(id, value, arr) {
    arr.forEach(function(item) {
        if (item.id == id) {
           item.name = value;
           return false;
        }
    });
}

updateThings("55555", "Mike", things);

document.body.innerHTML = '<pre>' + JSON.stringify(things, null, 4) + '</pre>';

【讨论】:

  • 如果我必须对一个非常大的数组进行 100 次不同的搜索,是否有更好的方法来做到这一点,或者是循环通过最佳选择?
  • @bryan 你几乎总是会以一种或另一种方式骑自行车。如今,计算机可以非常快地循环浏览数千个条目,所以我不会担心速度
  • 如果您必须进行 100 次搜索,它们可能是更好的方法,例如迭代一次并使用地图进行替换。
  • @adeneo 这很有意义。快速提问,而不是编辑值,是否有一个简单的解决方案来删除找到的“事物”?
  • 当然可以delete item.name
【解决方案2】:

我会遍历数组,检查 ID 是否匹配并编辑名称。

for (var i = 0; i < things.length; i++) {
    if (things[i].id == "55555") {
        things[i].name = "new name";
    }
}

【讨论】:

    【解决方案3】:

    使用.filter() 效率低下,因为它会在找到您要查找的项目后不断迭代。


    你可以像这样定义一个通用函数:

    function findElementByPropertyValue(arr, propertyName, propertyValue) {
        for (var i = 0, count = arr.length; i < count; i++) {
            var element = arr[i];
            if (element[propertyName] === propertyValue) {
                return element;
            }
        }
        return null;
    }
    

    然后像这样使用它:

    var mike = findElementByPropertyValue(things, 'id', '55555');
    if (mike) {
        mike.name = 'Mike';
    }
    

    jsfiddle


    如果您需要更改数组中的大量元素,您可能需要创建一个哈希对象。

    function createHashByProperty(arr, propertyName) {
        var hash = {};
        for (var i = 0, count = arr.length; i < count; i++) {
            var element = arr[i];
            hash[element[propertyName]] = element;
        }
        return hash;
    }
    

    你可以这样使用它:

    var hash = createHashByProperty(things, 'id');
    
    hash['55555'].name = 'Mike'; // Was 'Justin'
    hash['12345'].name = 'Brian'; // Was 'Bryan'
    

    jsfiddle


    上面的两个函数不会改变数组,它们只是允许你获取对数组中元素的引用,所以你可以改变这些元素。

    如果你想从数组中移除一个元素,你需要获取它的索引。然后您可以使用Array.prototype.splice 函数删除该元素。

    这是一个执行此操作的函数:

    function removeElementByPropertyValue(arr, propertyName, propertyValue) {
        for (var i = 0, count = arr.length; i < count; i++) {
            if (arr[i][propertyName] === propertyValue) {
                arr.splice(i, 1);
                return;
            }
        }
    }
    

    你可以这样使用它:

    removeElementByPropertyValue(things, 'id', '55555');
    

    jsfiddle


    注意:此答案中的代码使用纯 JavaScript;它不依赖于 jQuery 库。

    【讨论】:

      【解决方案4】:

      为了提高效率,您可以存储每个项目的位置,然后使用它来引用名称:

      var things = [
          {
              id: "12345",
              name: "Bryan"
          },
          {
              id: "55555",
              name: "Justin"
          }
      ], reference  = things.map(function(a){ return a.id });;
      
      function replace (id, name, ar, ref) { ref.indexOf(id)>-1&&(ar[ref.indexOf(id)]['name']=name); }
      
      replace("55555", "Phil", things, reference);
      

      在这种情况下,您只需要循环一次。然后所有信息都存储在reference 变量中。 reference 存储id 所在的位置,我们使用它来避免循环。我不确定编译器在做什么以及它是否循环,但这只是感觉更有效率。

      .indexOf 不完全受支持,因此您可以使用 PollyFill

      将此代码添加到 JavaScript 文件的顶部:

      [].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;})
      

      Array.prototype.map||(Array.prototype.map=function(r,t){var n,o,e;if(null==this)throw new TypeError(" this is null or not defined");var i=Object(this),a=i.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(n=t),o=new Array(a),e=0;a>e;){var p,f;e in i&&(p=i[e],f=r.call(n,p,e,i),o[e]=f),e++}return o});
      

      还有:

      Array.prototype.forEach||(Array.prototype.forEach=function(r,t){var o,n;if(null==this)throw new TypeError(" this is null or not defined");var e=Object(this),i=e.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(o=t),n=0;i>n;){var a;n in e&&(a=e[n],r.call(o,a,n,e)),n++}});
      

      检索自:hereherehere

      注意:虽然 IE 8 及更低版本不支持indexOf,但几乎所有其他浏览器都支持。

      【讨论】:

      • 我不认为 indexOf 具有跨浏览器支持,否则这种想法听起来不错。
      • @byran 我已经添加了 polyfill 来支持 IE 8 及以下版本
      猜你喜欢
      • 2021-05-31
      • 1970-01-01
      • 2018-08-22
      • 2021-09-24
      • 2017-08-03
      • 2021-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多