比较和添加项到对象数组



下面的代码应该:

1)遍历两个数组,

2)如果一个项在两个数组中都存在,则将其值与第一个数组中类似项的值相加,

3)如果在arr2中找到该项但不在arr1中,则将该项添加到arr1中。当两个数组具有相同的大小时,我的代码可以正常工作,但这是我使用不同大小的数组时得到的结果。

结果:

[[42岁的"保龄球"],[4,"脏袜子"],[2,"猫"],[6"杯子"],[2,"脏袜子"],[3,"破布"]]

应:

[[42岁的"保龄球"],[4,"脏袜子"],[2,"猫"],[3,"抹布"],[3,"杯子"]]

下面是我的代码:

function updateInventory(arr1, arr2) {
  for (var i = 0; i < arr1.length; i++) {
    for (var j = i; j < arr2.length; j++) {
      if (arr1[i][1] === arr2[j][1]) {
        arr1[i][0] += arr2[j][0];
      }
      if (arr1[i].indexOf(arr2[j][1]) === -1) {
        arr1.push(arr2[j]);
      }
      if (arr2.length > arr1.length) {
        arr1.push(arr2[arr2.length -1]);
      }
      else
        break;
    }
  }
  return arr1;
}
var curInv = [
    [21, "Bowling Ball"],
    [2, "Dirty Sock"],
    [2, "cat"],
];
var newInv = [
    [21, "Bowling Ball"],
    [2, "Dirty Sock"],
    [3, "rags"],
    [3, "mugs"]
];
updateInventory(curInv, newInv);

这里有什么问题?

您可以使用哈希表进行库存,并检查和更新currInv

var curInv = [[21, "Bowling Ball"], [2, "Dirty Sock"], [2, "cat"], ],
    newInv = [[21, "Bowling Ball"], [2, "Dirty Sock"], [3, "rags"], [3, "mugs"]],
    inventory = Object.create(null);
curInv.forEach(function (a) {
    this[a[1]] = a;
}, inventory);
newInv.forEach(function (a) {
    if (!this[a[1]]) {
        this[a[1]] = [0, a[1]];
        curInv.push(this[a[1]]);
    }
    this[a[1]][0] += a[0];
}, inventory);
console.log(curInv);
.as-console-wrapper { max-height: 100% !important; top: 0; }

我觉得你把事情弄得太复杂了。下面是一个工作片段:

function updateInventory(arr1, arr2) {
  for (var i = 0; i < arr2.length; i++) {
    var matchFound = false;
    for (var j = 0; j < arr1.length; j++) {
      if (arr1[j][1] === arr2[i][1]) {
        arr1[j][0] += arr2[i][0];
        matchFound = true;
      }
    }
    if (!matchFound) {
      arr1.push(arr2[i]);
    }
  }
  return arr1;
}
var curInv = [
  [21, "Bowling Ball"],
  [2, "Dirty Sock"],
  [2, "cat"],
];
var newInv = [
  [21, "Bowling Ball"],
  [2, "Dirty Sock"],
  [3, "rags"],
  [3, "mugs"]
];
console.log(updateInventory(curInv, newInv));

它的作用

  1. 循环arr2中的所有元素。
  2. 循环arr1中的所有元素。
  3. 如果匹配,将arr2中的项数与arr1中的对应项数相加。
  4. 如果没有找到匹配,将arr2中的元素添加到arr1中。

您可以合并数组或组合数组,以便它将自动执行您想要的操作。

var array3 = curInv.concat(newInv);

如果你想找到唯一的元素

//合并两个数组并获得唯一项var array3 = **

arrayUnique(array1.concat(array2));
function arrayUnique(array) {
   var a = array.concat(); 
   for(var i=0; i<a.length; ++i) { 
          for(var j=i+1; j<a.length; ++j) {
             if(a[i] === a[j]) a.splice(j--, 1); } 
     } 
   return a; 
}
* *

这里是一个简洁的函数式编程风格的解决方案,它使用哈希(实际上是Map)来提高效率:

function updatedInventory(a, b) {
    return Array.from(
        b.reduce( (m, [v,k]) => m.set(k, (m.get(k) || 0) + v),
                   new Map(a.map ( ([v,k]) => [k,v] )) ), // swap pairs
        ([k,v]) => [v,k]) // swap back afterwards;
}
// Sample data
var curInv = [
    [21, "Bowling Ball"],
    [2, "Dirty Sock"],
    [2, "cat"],
];
var newInv = [
    [21, "Bowling Ball"],
    [2, "Dirty Sock"],
    [3, "rags"],
    [3, "mugs"]
];
// call the function
curInv = updatedInventory(curInv, newInv);
// Output the result
console.log(curInv);
.as-console-wrapper { max-height: 100% !important; top: 0; }

如果您的数据有对,其中名称在第一个元素中,数字在第二个元素中,那么代码将会短得多。这是因为Map对象是用键-值对初始化的,而不是值-键对:

function updatedInventory(a, b) {
    return [...b.reduce( (m, [v,k]) => m.set(k, (m.get(k) || 0) + v), new Map(a) )];
}
// Sample data
var curInv = [
    ["Bowling Ball", 21],
    ["Dirty Sock", 2],
    ["cat", 2],
];
var newInv = [
    ["Bowling Ball", 21],
    ["Dirty Sock", 2],
    ["rags", 2],
    ["mugs", 2]
];
// call the function
curInv = updatedInventory(curInv, newInv);
// Output the result
console.log(curInv);
.as-console-wrapper { max-height: 100% !important; top: 0; }

因为这个函数不会改变传递的参数,而是返回结果,所以我把它命名为updatedInventory而不是updateInventory

所试代码的问题
  1. 您的外部循环位于第一个数组上,但这不是很实际,因为您将很难识别其中缺失的值。你应该先循环遍历第二个数组。然后,您将找到第一个数组中缺少的元素。

  2. 似乎没有很好的理由在外部循环当前所在的索引处开始内部循环。所以最好从0开始。与第一点一起,这将使循环看起来像这样:

    for (var j = 0; j < arr2.length; j++) {
      for (var i = 0; i < arr1.length; i++) {
    
  3. 当找到匹配时,没有理由进一步查找,因此您应该退出内部循环:

        if (arr1[i][1] === arr2[j][1]) {
          arr1[i][0] += arr2[j][0];
          break;
        }
    
  4. 您拥有的第二个if实际上正在启动第三个循环,因为indexOf执行迭代。此外,您正在寻找arr1[i],它只有两个元素:一个值和一个键。我敢肯定那不是你的本意。

    相反,这段代码应该被移出内部循环,并被纠正成这样(再次,考虑到你的循环是根据第2点交换的):

      if (i >= arr1.length) { // this indicates no match was found
        arr1.push(arr2[j]);
      }
    
  5. 第三个if试图对齐数组的长度,但它可以很好地添加一个已经存在于另一个数组中的元素!所以这个必须去掉。事实上,前面建议的更正已经使数组对齐。

  6. 你的break真的杀了它,让你错过了比赛,这是你为什么得到一个副本的核心原因(连同问题4)。这里没有理由中断,因为第一个if可能在下一个迭代中为真,所以您仍然应该给它一个机会。

相关内容

  • 没有找到相关文章

最新更新