通过嵌套数组循环JSON以查看所有值是否相等

时间:2018-12-05 14:56:00

标签: javascript arrays node.js json

基本上,我想看看有多少人购买同一供应商,以及有多少人一起购买了不同的品牌。我已经事先知道了品牌

我想遍历此JSON响应中的所有对象,如果所有“ line_items”的“ vendor”值相同,则控制台日志“这些订单具有相同的品牌” +订单号。如果它们是不同的控制台日志,则“这些订单具有不同的品牌” +订单号

{
  "orders": [
    {
      "email": "bob.norman@hostmail.com",
      "order_number": 1001,
      "line_items": [
        {
          "id": 466157049,
          "variant_title": "green",
          "vendor": "Windows"
        },
        {
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Windows"
          }

      ]
    },
    {
        "email": "john.candy@hostmail.com",
        "order_number": 1002,
        "line_items": [
          {
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Windows"
          },
          {
              "id": 466157049,
              "variant_title": "green",
              "vendor": "Apple"
            },
            {
              "id": 466157049,
              "variant_title": "green",
              "vendor": "Windows"
            }
  
        ]
      }
  ]
}

2 个答案:

答案 0 :(得分:1)

让我们从一个检查数组的所有元素是否相等的函数开始:

const allEqual = ([x, ...ys]) =>
  ys.every(y => y === x);

console.log(
  allEqual([1, 2, 2]),  // false
  allEqual([1, 1, 1]),  // true
  allEqual([1]),        // true
  allEqual([])          // true
);

通过这种方式,我们可以像这样检查单个供应商的商品清单:

const itemsAreSameVendor = items =>
  allEqual(items.map(({ vendor }) => vendor));

要检查订单是否为“单一供应商订单”,我们编写:

const orderIsSingleVendor = ({ line_items }) => 
  itemsAreSameVendor(line_items);

现在,查找单个订单是一个问题:

const singleCount = orderData.orders.filter(orderIsSingleVendor).length;
const multiCount = orderData.orders.length - singleCount;

或者,您可以使用reduce来组成两个方便的组:

const allEqual = ([x, ...ys]) => 
  ys.every(y => y === x);
  
const itemsAreSameVendor = items =>
  allEqual(items.map(({ vendor }) => vendor));

const orderIsSingleVendor = ({ line_items }) => itemsAreSameVendor(line_items);

console.log(
  orderData().orders.reduce(
    ({ singleVendorOrders, multiVendorOrders }, order) => {
      // Check if this order contains multiple vendors
      const orderType = orderIsSingleVendor(order)
        ? singleVendorOrders
        : multiVendorOrders;

      // Push to the right list
      orderType.push(order.order_number);
      
      return { singleVendorOrders, multiVendorOrders };
    },
    // Format of the result
    { singleVendorOrders: [], multiVendorOrders: [] }
  )
)

function orderData() {
  return {
    "orders": [{
        "email": "bob.norman@hostmail.com",
        "order_number": 1001,
        "line_items": [{
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Windows"
          },
          {
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Windows"
          }
        ]
      },
      {
        "email": "john.candy@hostmail.com",
        "order_number": 1002,
        "line_items": [{
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Windows"
          },
          {
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Apple"
          },
          {
            "id": 466157049,
            "variant_title": "green",
            "vendor": "Windows"
          }

        ]
      }
    ]
  };
}

PS:您尚未真正显示出需要帮助的确切部分...如果您对问题进行自己的尝试,您将获得更好的答案,并且人们将能够指出现有的答案解决类似的问题。

答案 1 :(得分:0)

将JSON加载到您的代码中

首先,您必须加载JSON。如果要从本地存档中加载它,则必须为此创建一个函数来加载它。由于加载归档文件是一个异步操作,因此您需要传递一个回调函数,以告诉函数在完成加载后如何处理该数据。在该回调中,您将告诉程序如何处理JSON。

Here's一个实现此功能的函数。您也可以使其通用,并为其提供参数以指定文件位置,然后替换“ my_data.json”部分。

如果您想使用对API的GET调用来获取JSON或使用Node.js来获取自己的后端(因为问题的标签为node.js),则可以使用Node.js的HTTPS module。 / p>

在此模块中,您将要专门使用this part,它是一个传递选项或带有回调的URL的GET。

处理JSON

一旦您准备好JSON并将其存储在变量中,您将需要首先对其进行解析,因为它将以字符串形式出现。

var parsedJSON = JSON.parse(myJson); //Where myJson is a variable where it is stored

然后,您将准备好带有嵌套对象数组的Javascript对象。

现在进入循环:

parsedJSON.orders.forEach((order) => {
  let areEqual = order['line_items'].reduce((result, item, currentIndex, items) => {
    if (currentIndex === 0) {
        return true;
    }

    if (currentIndex - 1 < items.length) {
        const previousVendor = items[currentIndex - 1].vendor; //Previous one
        if (y.vendor !== previousVendor) //We compare them
          return result && false; //Since they are different we use the logic operator && with false so this is enough to say that there is an instance where there are at least two different
    }

    return result && true; // <= If they are equal. We can just return acc aswell
  });

  if (areEqual) console.log(order['order_number']);
});

如果您希望此功能适用于IE11,请少注意您不能像我一样使用箭头功能。只需将它们更改为正则函数表达式即可。 Here's关于Java数组

的reduce函数的更多信息