【问题标题】:Comparing one value from two arrays if bigger then copying + combining into third array比较两个数组中的一个值(如果大于则复制+组合到第三个数组)
【发布时间】:2022-01-04 18:43:33
【问题描述】:

我正在尝试制作一个简单的应用程序来通过 REST API 在 WooCommerce 中更新价格。

我的 arrayOne 有 SKU + 来自我的 ERP 的更新价格

[
 {sku=PD-1000-B, price=9800.00},
 {sku=PD-1007-A, price=9678.16}
]

arrayTwo 包含来自 woocommerce 的所有产品、SKU、id(我需要获取)和当前价格

[
 {sku=PD-1000-B, id=1622.0, price=8145.9},
 {sku=PD-1007-A, id=1624.0, price=9678.16}
]

我想将arrayTwo 与arrayOne 进行比较,如果arrayOne 中的价格更大,那么将所有巧合合并并创建新数组。像这样的

[
 {sku=PD-1000-B, id=1622.0, price=9800.00}
]

因为唯一更大的价格是 PD-1000-B。

到目前为止,我所做的只是创建一个新的 Set,但这并不能比较任何东西,我的想法是减少仅更改要更新的数量。

编辑:截至目前,我只是用 arrayOne 中的价格替换 arrayTwo 中的价格:

let set = new Set();
for (let i = 0; i < data.length; i++)
    set.add(data[i]['sku'])
for (let i = 0; i < container.length; i++)
    if (set.has(container[i]['sku']))
        container[i]['price'] = data[i]['price'];

container 是一个空变量,我用来收集从 WooCommerce 获得的数据作为一个数组,而 data 是一个包含更新价格 + sku 的数组。

谢谢。

【问题讨论】:

  • 查看我的答案,如果它解决了您的问题,请告诉我 +^

标签: javascript arrays api google-apps-script woocommerce


【解决方案1】:

您可以分两步实现:

  1. arrOne 中找到最伟大的
  2. arrTwo中对应的比较

您可以使用这个不错的功能:

const arrOne = [
  {
    sku: "PD-1000-B",
    price: 9678.16
  },
  {
    sku: "PD-1000-B",
    price: 9800.00
  },
  {
    sku: "PD-1007-C",
    price: 9714.16
  },
  {
    sku: "PD-1007-C",
    price: 9270.00
  }
]

const arrTwo = [
 {sku: "PD-1000-B", id:1622.0, price:8145.9},
 {sku: "PD-1007-A", id:1624.0, price:9678.16},
 {sku: "PD-1007-C", id:1627.0, price:9478.16},
]

const findAllHighest = (arr) => {
  // 1) get highest one of each in arrOne
  const arrOneGreatest = arr.reduce((prev, cur) => {
    if(!prev[cur.sku]){
      prev[cur.sku] = cur
      return prev
    }

    if(cur.price > prev[cur.sku].price){
      prev[cur.sku] = cur
    }
    return prev
  }, {})
  
  // match to arrayTwo
  const result = arrTwo.map(el => {
    const arrOneObj = Object.values(arrOneGreatest).find(n => n.sku === el.sku)

    if(!arrOneObj)
      return el

    if(arrOneObj.price > el.price)
      el.price = arrOneObj.price
    return el
  }, [])
  
  return result
}

console.log(findAllHighest(arrOne))
 .as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 您好,谢谢您的回答!我仍然是 JS 的菜鸟。这部分工作,即使它比较它并只更新最大的价格它仍然返回我认为的数组中的所有项目,假设我正确使用你的代码,因为我不完全理解它。 [{sku=PD-1000-B, id=1622.0, price=8145.9}, {id=1624.0, price=60000.0, sku=PD-1007-A}, {price=8023.12, id=1625.0, sku=PD-1014}, {sku=PD-1026, price=7139.21, id=1627.0}, {id=1629.0, price=650000.0, sku=PD-1028}, {id=1630.0, sku=PD-1028-B, price=13000.0}, {price=9491.81, id=1631.0, sku=PD-1029A}]
  • 我知道我没有告诉你太多,因为我读了我的回复。基本上,第一个没有价格变化,第二个是这样的堡垒。在您的示例中,它仅显示价格发生变化的那些。
  • 项目总数?每个阵列大约 30k。每次更新我会批量更新 100 个。
  • 我在代码中发现了一个错误。它返回的项目比 arrTwo 少。现在修好了。 '每次更新我将批量更新 100'。没关系,试试看
  • 每个阵列 30k 但我用很少的产品进行测试,只有 10 个。从你的代码中,我将 console.log(findAllHighest(arrOne))console.log(findAllHighest(data))const result = arrTwo.map(el =&gt;const result = container.map(el =&gt; 切换我觉得就是这样我应该修改了吧?
【解决方案2】:

我会这样尝试:

var arrayOne = [
    {sku: 'PD-1000-B', price: 9800.00},
    {sku: 'PD-1007-A', price: 9678.16}
];

var arrayTwo = [
    {sku: 'PD-1000-B', id: 1622.0, price: 8145.9},
    {sku: 'PD-1007-A', id: 1624.0, price: 9678.16}
];

// convert the array into the object {sku1: {}, sku2: {}, ...}
var arrayOne_obj = {}
for (let obj of arrayOne)
    arrayOne_obj[obj.sku] = {'price': obj.price};

// convert the array into the object {sku1: {}, sku2: {}, ...}
var arrayTwo_obj = {}
for (let obj of arrayTwo)
    arrayTwo_obj[obj.sku] = {'price': obj.price, 'id': obj.id};

// loop through the 'sku'-subobjects of the 'arrayOne_obj' object
// compare its prices with prices of the same 'sku'-subobject of 'arrayTwo_obj',
// and make the output array
var output = [];
for (let sku in arrayOne_obj) {
    let subObjOne = arrayOne_obj[sku];
    let subObjTwo = arrayTwo_obj[sku];
    if (subObjOne.price > subObjTwo.price) {
        output.push({'sku':sku, 'id': subObjTwo.id, 'price':subObjOne.price});
    }  
}

console.log(output); // output [ {sku: 'PD-1000-B', id:1622.0, price:9800.00} ]
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这似乎 100% 完全符合我的需要,但我收到一个错误:“TypeError: Cannot read property 'price' of undefined” - 第 83 行 if (subObjOne.price &gt; subObjTwo.price) { 我觉得奇怪...我在想也许我还没有填充依赖数组? pastebin.com/apsAQVg9 这是整个代码,我只更改了我拥有的数组名称。这两个中的一个,容器在循环信息后被填充,但它应该是,因为我已经记录了它并且它显示在第 83 行的错误之前。
  • 我很确定错误的发生是因为数组。该代码适用于测试数组。您能否展示一下数组containerdata 的外观?
  • 我可以! pastebin.com/s0JABm2k 这是部分的,因为它是 30k+,输出会很大,这两个 sn-ps 是日志。数据和容器
  • 感谢您的澄清。现在很明显了。数组container 比数组data 短。所以有两种可能的解决方案:像这样迭代较短的数组containerfor (let sku in arrayTwo_obj) { 或使用try {} catch() {}。问题是较大的对象arrayOne_obj(数据)有一些sku 子对象,而较小的对象arrayTwo_obj(容器)没有。这就是出现错误的原因。
  • 以防万一循环通过较小数组的代码在这里:pastebin.com/ra5GSznr 这里是与try {} catch(e) {} 相同的代码:pastebin.com/UV5VsRjZ 他们都得到相同的正确结果。但是如果你确定“容器”数组总是比“数据”短,第一个解决方案会更有效
猜你喜欢
  • 1970-01-01
  • 2017-11-11
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多