在lodash中有一个函数来替换匹配的项目

 飞翔的10号 发布于 2022-12-04 01:06

我想知道在lodash中是否有一个更简单的方法来替换JavaScript集合中的项目?(可能重复,但我不明白那里的答案:)

我看了他们的文档但找不到任何东西

我的代码是:

var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Can following code be reduced to something like _.XX(arr, {id:1}, {id:1, name: "New Name"});
_.each(arr, function(a, idx){
  if(a.id === 1){
    arr[idx] = {id:1, name: "Person New Name"};
    return false;
  }
});

_.each(arr, function(a){
  document.write(a.name);
});

更新: 我正在尝试替换的对象有许多属性,如

{id:1,Prop1:...,Prop2:...,依此类推}

解:

感谢dfsq,但我在lodash中找到了一个合适的解决方案,似乎工作正常并且非常整洁,我把它放在mixin中,因为我在很多地方都有这个要求.JSBin

var update = function(arr, key, newval) {
  var match = _.find(arr, key);
  if(match)
    _.merge(match, newval);
  else
    arr.push(newval);    
};

_.mixin({ '$update': update });

var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];

_.$update(arr, {id:1}, {id:1, name: "New Val"});


document.write(JSON.stringify(arr));

更快的解决方案 正如@dfsq所指出的,以下方法更快

var upsert = function (arr, key, newval) {
    var match = _.find(arr, key);
    if(match){
        var index = _.indexOf(arr, _.find(arr, key));
        arr.splice(index, 1, newval);
    } else {
        arr.push(newval);
    }
};

dfsq.. 170

在您的情况下,您需要做的就是在数组中查找对象并使用Array.prototype.splice方法:

var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];

// Find item index using _.findIndex (thanks @AJ Richardson for comment)
var index = _.findIndex(arr, {id: 1});

// Replace item at index using native splice
arr.splice(index, 1, {id: 100, name: 'New object.'});

// "console.log" result
document.write(JSON.stringify( arr ));

6 个回答
  • functionfindAndReplace(arr,find,replace){ leti; for(i=0;i<arr.length&&arr[i].id!=find.id;i++){} i<arr.length?arr[i]=replace:arr.push(replace); } 现在让我们测试所有方法的性能: //TCsfirstapproach functionfirst(arr,a,b){ _.each(arr,function(x,idx){ if(x.id===a.id){ arr[idx]=b; returnfalse; } }); } //solutionwithmerge functionsecond(arr,a,b){ constmatch=_.find(arr,a); if(match){ _.merge(match,b); }else{ arr.push(b); } } //mostvotedsolution functionthird(arr,a,b){ constmatch=_.find(arr,a); if(match){ varindex=_.indexOf(arr,_.find(arr,a)); arr.splice(index,1,b); }else{ arr.push(b); } } //myapproach functionfourth(arr,a,b){ letl; for(l=0;l<arr.length&&arr[l].id!=a.id;l++){} l<arr.length?arr[l]=b:arr.push(b); } functiontest(fn,times,el){ constarr=[],size=250; for(leti=0;i<size;i++){ arr[i]={id:i,name:`name_${i}`,test:test}; } letstart=Date.now(); _.times(times,()=>{ constid=Math.round(Math.random()*size); consta={id}; constb={id,name:`${id}_name`}; fn(arr,a,b); }); el.innerHTML=Date.now()-start; } test(first,1e5,document.getElementById(first)); test(second,1e5,document.getElementById(second)); test(third,1e5,document.getElementById(third)); test(fourth,1e5,document.getElementById(fourth)); <scriptsrc=https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js></script> <div> <ol> <li><bid=first></b>ms[TCsfirstapproach]</li> <li><bid=second></b>ms[solutionwithmerge]</li> <li><bid=third></b>ms[mostvotedsolution]</li> <li><bid=fourth></b>ms[myapproach]</li> </ol> <div>
    2022-12-11 01:55 回答
  • 您还可以使用findIndex和pick来实现相同的结果:

      var arr  = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
      var data = {id: 2, name: 'Person 2 (updated)'};
      var index = _.findIndex(arr, _.pick(data, 'id'));
      if( index !== -1) {
        arr.splice(index, 1, data);
      } else {
        arr.push(data);
      }
    

    2022-12-11 02:08 回答
  • 在您的情况下,您需要做的就是在数组中查找对象并使用Array.prototype.splice方法:

    var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
    
    // Find item index using _.findIndex (thanks @AJ Richardson for comment)
    var index = _.findIndex(arr, {id: 1});
    
    // Replace item at index using native splice
    arr.splice(index, 1, {id: 100, name: 'New object.'});
    
    // "console.log" result
    document.write(JSON.stringify( arr ));
    <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
    2022-12-11 02:12 回答
  • [ES6]此代码适用于我.

    let result = array.map(item => item.id === updatedItem.id ? updatedItem : item)
    

    2022-12-11 02:15 回答
  • 随着时间的流逝,您应该采用一种更具功能性的方法,在这种方法中,您应该避免数据突变并编写小的,单一责任的函数。与ECMAScript 6个标准,你可以在JavaScript中享受函数式编程范式与所提供的mapfilterreduce方法。您不需要其他破折号,下划线或其他可以执行大多数基本操作的内容。

    下面,我提供了一些针对此问题的建议解决方案,以展示如何使用不同的语言功能来解决此问题:

    使用ES6地图:

    const replace = predicate => replacement => element =>
      predicate(element) ? replacement : element
     
    const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
    const predicate = element => element.id === 1
    const replacement = { id: 100, name: 'New object.' }
    
    const result = arr.map(replace (predicate) (replacement))
    console.log(result)
    2022-12-11 02:15 回答
  • 似乎最简单的解决方案是使用ES6 .map或lodash _.map:

    var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
    
    // lodash
    var newArr = _.map(arr, function(a) {
      return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
    });
    
    // ES6
    var newArr = arr.map(function(a) {
      return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
    });
    

    这具有避免改变原始数组的良好效果.

    2022-12-11 02:55 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有