【问题标题】:Return formatted object with only positive values返回仅具有正值的格式化对象
【发布时间】:2020-06-29 07:01:41
【问题描述】:

我有一个对象。我的每个嵌套对象都有一个作为嵌套数组的价格,其中可能包含负值。 我需要格式化对象并返回一个新的对象,其中子对象只包含正值。

例如, 在下面的代码中,理想情况下,它应该只返回具有“TypeB”对象的对象,因为只有具有非负值的价格。

我试过这个,但我想我错过了一些东西。 另外,我可以改用'reduce'方法来优化它吗?

输入对象:

{
  "TypeA": [
    {
      "price": [
        [
          {
            "amount": -45,
            "currency": "USD"
          }
        ]
      ],
      "name": "ABC",
      "priceDetails": [
        {
          "name": "BASE",
          "price": [
            [
              {
                "amount": -40.00,
                "currency": "USD"
              }
            ]
          ]
        },
        {
          "name": "TAX",
          "price": [
            [
              {
                "amount": -5.00,
                "currency": "USD"
              }
            ]
          ]
        }
      ]
    }
  ],
  "TypeB": [
    {
      "price": [
        [
          {
            "amount": 0,
            "currency": "USD"
          }
        ]
      ],
      "name": "ABC",
      "priceDetails": [
        {
          "name": "BASE",
          "price": [
            [
              {
                "amount": 0,
                "currency": "USD"
              }
            ]
          ]
        }
      ]
    }
  ]
}

预期输出:

{
  "TypeB": [
    {
      "price": [
        [
          {
            "amount": 0,
            "currency": "USD"
          }
        ]
      ],
      "name": "ABC",
      "priceDetails": [
        {
          "name": "BASE",
          "price": [
            [
              {
                "amount": 0,
                "currency": "USD"
              }
            ]
          ]
        }
      ]
    }
  ]
}

代码:

const data = {
  "TypeA": [{
    "price": [
      [{
        "amount": -45,
        "currency": "USD"
      }]
    ],
    "name": "ABC",
    "priceDetails": [{
        "name": "BASE",
        "price": [
          [{
            "amount": -40.00,
            "currency": "USD"
          }]
        ]
      },
      {
        "name": "TAX",
        "price": [
          [{
            "amount": -5.00,
            "currency": "USD"
          }]
        ]
      }
    ]
  }],
  "TypeB": [{
    "price": [
      [{
        "amount": 0,
        "currency": "USD"
      }]
    ],
    "name": "ABC",
    "priceDetails": [{
      "name": "BASE",
      "price": [
        [{
          "amount": 0,
          "currency": "USD"
        }]
      ]
    }]
  }]
};

const formattedData = Object.values(data).filter(item => {
  return item.map(elem => {
    const itemPrice = elem.price;
    const isPositive = itemPrice[0][0].amount >= 0;
    return isPositive ? elem : false;
  });
});
console.log(formattedData);

【问题讨论】:

    标签: javascript arrays object filter reduce


    【解决方案1】:

    可以使用Object.entries 将您的对象设为数组,然后通过检查every 的数量是否大于0,只需filter

    const filtered = Object.entries(data).filter(([k, v]) =>
        v.every(s=> s.price.every(s1 => s1.every(s2 => s2.amount >= 0 )))
        && v.every(pd => pd.priceDetails.every(pdp => 
            pdp.price.every(pr => pr.every(prr => prr.amount >= 0))))
    );
    

    一个例子:

    const data = {
        "TypeA": [{
            "price": [ [{ "amount": -45, "currency": "USD"  }]
            ],
            "name": "ABC",
            "priceDetails": [{
                "name": "BASE",
                "price": [[{  "amount": -40.00, "currency": "USD" }]]
            },
            {
                "name": "TAX",
                "price": [ [{ "amount": -5.00, "currency": "USD" }]]
            }
            ]
        }],
        "TypeB": [{
            "price": [ [{"amount": 0, "currency": "USD" }]],
            "name": "ABC",
            "priceDetails": [{
                "name": "BASE",
                "price": [[{"amount": 0, "currency": "USD"}]]
            }]
        }]
    };
    
    const filtered = Object.entries(data).filter(([k, v]) =>
        v.every(s=> s.price.every(s1 => s1.every(s2 => s2.amount >= 0 )))
        && v.every(pd => pd.priceDetails.every(pdp => pdp.price.every(pr => pr.every(prr => prr.amount >= 0))))
    );
    
    const result = Object.fromEntries(filtered);
    console.log(result);

    【讨论】:

      【解决方案2】:

      如果找到想要的叶子对象,您可以使用各种检查过滤数据并构建一个新对象。

      function filter(object) {
          if (!object || typeof object !== 'object') return;
      
          if ('amount' in object) return object.amount >= 0 ? object : undefined;
      
          if (Array.isArray(object)) {
              var items = object.reduce((r, v) => {
                  var temp = filter(v);
                  if (temp) r.push(temp);
                  return r;
              }, []);
              return items.length ? items : undefined;
          } else {
              var entries = Object.entries(object).reduce((r, [k, v]) => {
                  var temp = filter(v);
                  if (temp) r.push([k, temp]);
                  return r;
              }, []);
              return entries.length ? Object.fromEntries(entries) : undefined;
          }
      }
      
      var data = { TypeA: [{ price: [[{ amount: -45, currency: "USD" }]], name: "ABC", priceDetails: [{ name: "BASE", price: [[{ amount: -40, currency: "USD" }]] }, { name: "TAX", price: [[{ amount: -5, currency: "USD" }]] }] }], TypeB: [{ price: [[{ amount: 0, currency: "USD" }]], name: "ABC", priceDetails: [{ name: "BASE", price: [[{ amount: 0, currency: "USD" }]] }] }] },
          result = filter(data);
      
      console.log(result);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        【解决方案3】:

        cc = {
          "TypeA": [
            {
              "price": [
                [
                  {
                    "amount": -45,
                    "currency": "USD"
                  }
                ]
              ],
              "name": "ABC",
              "priceDetails": [
                {
                  "name": "BASE",
                  "price": [
                    [
                      {
                        "amount": -40.00,
                        "currency": "USD"
                      }
                    ]
                  ]
                },
                {
                  "name": "TAX",
                  "price": [
                    [
                      {
                        "amount": -5.00,
                        "currency": "USD"
                      }
                    ]
                  ]
                }
              ]
            }
          ],
          "TypeB": [
            {
              "price": [
                [
                  {
                    "amount": 0,
                    "currency": "USD"
                  }
                ]
              ],
              "name": "ABC",
              "priceDetails": [
                {
                  "name": "BASE",
                  "price": [
                    [
                      {
                        "amount": 0,
                        "currency": "USD"
                      }
                    ]
                  ]
                }
              ]
            }
          ]
        }
        
        const dd = Object.keys(cc).reduce((acc, item) => {
          if (cc[item][0].price[0][0].amount >= 0) {
            acc[item] = cc[item];
           }
        return acc;
        }, {});
        console.log(dd)

        试试这个

        const result = Object.keys(data).filter(i => data[i][0].price[0][0].amount >= 0).map(y => data[y])
        console.log(result) // positive amount array
        

        编辑:使用减速器

        const dd = Object.keys(data).reduce((acc, item) => {
          if (data[item][0].price[0][0].amount >= 0) {
            acc[item] = data[item];
           }
        return acc;
        }, {});
        

        【讨论】:

        • 我得到一个数组,但预期的结果是一个对象,它也具有原始键。请检查我上面问题中的预期输出。
        • 刚刚更新了我的答案,希望这是您所期望的。请检查sn-p。 @Sunny
        猜你喜欢
        • 2020-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多