比较2个数组并替换匹配键中的值

Compare 2 arrays and replace values from keys that match?

本文关键字:2个 数组 替换 比较      更新时间:2023-09-26

这是我的尝试。

问题: 当前我的return ds1.locale = dataSrc2[i][property]线路是一个故障点我知道map返回一个新数组;但是,除了ds1.locale之外,我想要原始dataSrc1的属性和值。

问题:如何在继承dataSrc1的原始其他键值对的同时返回数组,dataSrc1.locale除外,该值被匹配的dataSrc2键值替换。

UPDATE我解决了它。但代码真的很难看。有更好的方法吗?也许不用3个该死的循环?

以下是步骤的伪代码。

//1. loop over dataSrc1.
//2. loop over dataSrc2.
//3. try find a match from dataSrc2[key] e.g. dataSrc2['af'] === dataSrc1.locale;
//4. if matched save dataSrc2's key
//5. replace dataSrc1.language = dataSrc2[savedDataSrc2Key]
var dataSrc1 = [{'locale': 'af', 'language': 'Afrikaans'}, {'locale': 'ar', 'language': 'Arabic'}];
var dataSrc2 = [{'ar': '丹麥文'},{'af': '土耳其文'}];
//Intended output
//dataSrc3 = [{'locale': 'af', 'language': '土耳其文'}, {'locale': 'ar', 'language': '丹麥文'}]

Repl代码

var dataSrc3 = dataSrc1.map(function(ds1){
    for(var i = 0; i < dataSrc2.length; i += 1){
        for (var property in dataSrc2[i]) {
            if (dataSrc2[i].hasOwnProperty(property)) {
                if(property === ds1.locale){
                    ds1.language = dataSrc2[i][property];
                    return ds1; 
                }
            }
        }
    }
})
console.log(dataSrc3);
//Current output
//[ '土耳其文', '丹麥文' ]
//Intended output
//dataSrc3 = [{'locale': 'af', 'language': '土耳其文'}, {'locale': 'ar', 'language': '丹麥文'}]

您可以进行一点重构:

var dataSrc3 = dataSrc1.map(function(d1) {
  var language = null;
  // .some will iterate until you return true or last item is passed
  // set variable language to found language
  dataSrc2.some(function(d) {
    if (Object.prototype.hasOwnProperty.call(d, d1.locale)) {
      language = d[d1.locale];
      return true;
    }
  });
  // return a new object, this will not modify the objects in dataSrc1 and dataSrc2
  return { language: language, locale: d1.locale };
});
console.log(dataSrc3); // [{'locale': 'af', 'language': '土耳其文'}, {'locale': 'ar', 'language': '丹麥文'}]

有一种叫做.find的实验数组方法,它的工作原理有点像.some,但会给你数组中的当前值:

var dataSrc3 = dataSrc1.map(function(d1) {
  var d2 = dataSrc2.find(function(d2) {
    return Object.prototype.hasOwnProperty.call(d2, d1.locale);
  });
  // return a new object, this will not modify the objects in dataSrc1 and dataSrc2
  return { 
    language: d2[d1.locale], 
    locale: d1.locale 
  };
});
console.log(dataSrc3); // [{'locale': 'af', 'language': '土耳其文'}, {'locale': 'ar', 'language': '丹麥文'}]

你可能想看看undercore.js或lodash。这些库将提供可用于旧浏览器的实用util函数:

var dataSrc3 = _.map(dataSrc1, function(d1) {
  var d2 = _.find(dataSrc2, function(d2) {
    return _.has(d2, d1.locale);
  });
  return { 
    language: d2[d1.locale], 
    locale: d1.locale 
  };
});

我们的代码中有两个错误:

return ds1.locale = dataSrc2[i][property];

这将分配给并返回ds1.locale,而您希望分配给ds1.language,并返回修改后的ds1:

ds1.language = dataSrc2[i][property];
return ds1;

其次,您还应该返回任何未修改的ds1,因此在for循环之后添加:

return ds1;

正如其他人所指出的,您可以更简洁地编写函数。