【问题标题】:count object based on status and shop using javascript?使用 javascript 根据状态和商店计数对象?
【发布时间】:2022-08-19 16:57:04
【问题描述】:

我有以下 JSON 数组我想在每个对象中创建一个新字段,这将是对象的计数

我们必须根据状态、商店和名称(所有者详细信息)进行计数

我怎样才能做到这一点,我在下面添加了我的预期输出

 var items = [
  {
    \"id\": 1,    
    \"status\": \"ORANGE\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]    
    
  },
  {
    \"id\": 2,
    \"status\": \"GREEN\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]
  },
  {
    \"id\": 3,
    \"status\": \"ORANGE\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]    
  },
  {
    \"id\": 4,
    \"status\": \"YELLOW\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]
  },
  {
    \"id\": 5,
    \"status\": \"RED\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]
  },
  {
    \"id\":6,
    \"status\": \"GREEN\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]
  },
  {
    \"id\": 7,
    \"status\": \"GREEN\",
    \"Shop\":\"XYZ\",
    \"ownerDetails\":[ {\"name\":\"test2\",\"address\":\"test2\"}]
  },
   {
    \"id\": 8,
    \"status\": \"ORANGE\",
    \"Shop\":\"XYZ\",
    \"ownerDetails\":[ {\"name\":\"test2\",\"address\":\"test2\"}]    
  },
  {
    \"id\": 9,
    \"status\": \"YELLOW\",
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}]
  },
  {
    \"id\": 10,
    \"status\": \"GREEN\",
    \"Shop\":\"EFG\",
    \"ownerDetails\":[ {\"name\":\"test3\",\"address\":\"test3\"}]
  },
{
    \"id\": 11,
    \"status\": \"GREEN\",
    \"Shop\":\"EFG\",
    \"ownerDetails\":[ ]
  }
] 

预期输出:因此,我们必须根据每个商店、状态和名称(ownerDetails)来计算对象

    [
  {
    \"id\": 1,    
    \"status\": \"ORANGE\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 2
  },
  {
    \"id\": 2,
    \"status\": \"GREEN\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 2
  },
  {
    \"id\": 3,
    \"status\": \"ORANGE\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 2
  },
  {
    \"id\": 4,
    \"status\": \"YELLOW\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 2
  },
  {
    \"id\": 5,
    \"status\": \"RED\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 1
  },
  {
    \"id\":6,
    \"status\": \"GREEN\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 2
  },
  {
    \"id\": 7,
    \"status\": \"GREEN\"
    \"Shop\":\"XYZ\",
    \"ownerDetails\":[ {\"name\":\"test2\",\"address\":\"test2\"}],
    \"Count\": 1
  },
   {
    \"id\": 8,
    \"status\": \"ORANGE\"
    \"Shop\":\"XYZ\",
    \"ownerDetails\":[ {\"name\":\"test2\",\"address\":\"test2\"}],
    \"Count\": 1
  },
  {
    \"id\": 9,
    \"status\": \"YELLOW\"
    \"Shop\":\"ABC\",
    \"ownerDetails\":[ {\"name\":\"test1\",\"address\":\"test1\"}],
    \"Count\": 2
  },
  {
    \"id\": 10,
    \"status\": \"GREEN\"
    \"Shop\":\"EFG\"
    \"ownerDetails\":[ {\"name\":\"test3\",\"address\":\"test3\"}],
    \"Count\": 1
  },
{
\"id\": 11,
\"status\": \"GREEN\",
\"Shop\":\"EFG\",
\"ownerDetails\":[ ],
\"Count\": 1
}
] 

请看demo

感谢@Nico_ 和@Parth Ravalhelp

下面的代码在\"ownerDetails\":[ ] 时不起作用,我在控制台中收到以下错误Cannot read properties of undefined (reading \'name\')

代码 :

const itemsWithCount = items.map(item => ({
  ...item,
   Count: items.filter(({ status, Shop ,ownerDetails: [{ name }]}) => item.status === status && item.Shop === Shop && item.ownerDetails[0].name === name).length
}));

console.log(itemsWithCount)
  • 你有没有尝试过,如果是的话,你能分享一下吗?如果没有,请尝试使用new Map() 构造一个映射,其键将是statusShop 的组合,值将是一个计数。使用它,您可以转换当前数组,以便每个对象都有一个计数。
  • 到目前为止,请显示您的代码。

标签: javascript arrays json angularjs


【解决方案1】:

var items = [{
    "id": 1,
    "status": "ORANGE",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]

  },
  {
    "id": 2,
    "status": "GREEN",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]
  },
  {
    "id": 3,
    "status": "ORANGE",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]
  },
  {
    "id": 4,
    "status": "YELLOW",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]
  },
  {
    "id": 5,
    "status": "RED",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]
  },
  {
    "id": 6,
    "status": "GREEN",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]
  },
  {
    "id": 7,
    "status": "GREEN",
    "Shop": "XYZ",
    "ownerDetails": [{
      "name": "test2",
      "address": "test2"
    }]
  },
  {
    "id": 8,
    "status": "ORANGE",
    "Shop": "XYZ",
    "ownerDetails": [{
      "name": "test2",
      "address": "test2"
    }]
  },
  {
    "id": 9,
    "status": "YELLOW",
    "Shop": "ABC",
    "ownerDetails": [{
      "name": "test1",
      "address": "test1"
    }]
  },
  {
    "id": 10,
    "status": "GREEN",
    "Shop": "EFG",
    "ownerDetails": [{
      "name": "test3",
      "address": "test3"
    }]
  }
];

var mapData = items.map((data) => {
  var getList = items.filter(word => word.Shop == data.Shop).length;
  return {
    id: data.id,
    status: data.status,
    Shop: data.Shop,
    text: data.ownerDetails,
    Count: getList
  };
});

console.log(mapData);

注意:- 地图数据和类似商店的计数......

【讨论】:

  • "ownerDetails":[ ] 并且我收到以下错误 Cannot read properties of undefined (reading 'name') in console.could you help.
【解决方案2】:

未定义对象的解构

/**
 * Problem: The deconstructed object is not defined.
 *
 * This will throw: TypeError: Cannot read properties of undefined (reading 'name')
 * 
 * This is roughly equivalent of doing const { name } = undefined
 */
const [{ name }] = [];

/**
 * Solution: Assign a default value when the deconstructed object is not defined.
 *
 * If the deconstructing object is undefined,
 * assign an empty object as the default value
 */
const [{ name } = {}] = [];

访问未定义对象的属性

如果您在比较 item.ownerDetails[0].name === name 之前没有检查 ownerDetails 数组是否为空,您最终可能会尝试访问不存在的对象的属性。这将导致像上面那样的 TypeError。

要处理这种情况,您必须:

  1. 验证item.owner详细信息中至少有一个元素;
  2. 验证名称属性是否存在于第一个元素上;

    如果测试通过,则返回 ownerDetails 的第一个元素的 name 属性值。否则,您必须提供默认值。

    工作示例

    const items = [
      { id: 1, status: 'ORANGE', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 2, status: 'GREEN', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 3, status: 'ORANGE', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 4, status: 'YELLOW', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 5, status: 'RED', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 6, status: 'GREEN', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 7, status: 'GREEN', Shop: 'XYZ', ownerDetails: [{ name: 'test2', address: 'test2' }] },
      { id: 8, status: 'ORANGE', Shop: 'XYZ', ownerDetails: [{ name: 'test2', address: 'test2' }] },
      { id: 9, status: 'YELLOW', Shop: 'ABC', ownerDetails: [{ name: 'test1', address: 'test1' }] },
      { id: 10, status: 'GREEN', Shop: 'EFG', ownerDetails: [{ name: 'test3', address: 'test3' }] },
      { id: 11, status: 'GREEN', Shop: 'EFG', ownerDetails: [] }
    ];
    
    const itemsWithCount = items.map(item => ({
      ...item,
      /**
       * If the first element of ownerDetails is not defined,
       * assign an empty object as the default value for the first
       * element of ownerDetails array.
       */
      Count: items.filter(({ status, Shop, ownerDetails: [{ name } = {}] }) =>
        item.status === status &&
        item.Shop === Shop &&
        (
          (
            /**
             * 1. Check if ownerDetails is not empty.
             */
            item.ownerDetails.length &&
            /**
             * 2. Check if the first element of item.ownerDetails has a name property.
             *
             * ESLint best practice:
             * ------------------------------------------------------
             * Disallow calling some Object.prototype methods directly on objects.
             * For more details, see https://eslint.org/docs/rules/no-prototype-builtins
             * ------------------------------------------------------
             */
            Object.prototype.hasOwnProperty.call(item.ownerDetails[0], 'name') &&
            /**
             * 3. Accessing and returning name property.
             */
            item.ownerDetails[0].name
            /**
             * Else, compare undefined with name property.
             */
          ) || undefined
        ) === name
      ).length
    }));
    
    console.log(itemsWithCount)

    输出

    [
      { Count: 2, id: 1, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'ORANGE' },
      { Count: 2, id: 2, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'GREEN' },
      { Count: 2, id: 3, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'ORANGE' },
      { Count: 2, id: 4, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'YELLOW' },
      { Count: 1, id: 5, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'RED' },
      { Count: 2, id: 6, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'GREEN' },
      { Count: 1, id: 7, ownerDetails: [{ address: 'test2', name: 'test2' }], Shop: 'XYZ', status: 'GREEN' },
      { Count: 1, id: 8, ownerDetails: [{ address: 'test2', name: 'test2' }], Shop: 'XYZ', status: 'ORANGE' },
      { Count: 2, id: 9, ownerDetails: [{ address: 'test1', name: 'test1' }], Shop: 'ABC', status: 'YELLOW' },
      { Count: 1, id: 10, ownerDetails: [{ address: 'test3', name: 'test3' }], Shop: 'EFG', status: 'GREEN' },
      { Count: 1, id: 11, ownerDetails: [], Shop: 'EFG', status: 'GREEN' }
    ]
    

【讨论】:

    【解决方案3】:

    您可以使用map 来循环遍历您的数组(顺便说一下,您需要在“Shop”之前添加一些逗号。

      const items = [
      {
        "id": 1,    
        "status": "ORANGE",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]    
        
      },
      {
        "id": 2,
        "status": "GREEN",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]
      },
      {
        "id": 3,
        "status": "ORANGE",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]    
      },
      {
        "id": 4,
        "status": "YELLOW",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]
      },
      {
        "id": 5,
        "status": "RED",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]
      },
      {
        "id":6,
        "status": "GREEN",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]
      },
      {
        "id": 7,
        "status": "GREEN",
        "Shop":"XYZ",
        "ownerDetails":[ {"name":"test2","address":"test2"}]
      },
       {
        "id": 8,
        "status": "ORANGE",
        "Shop":"XYZ",
        "ownerDetails":[ {"name":"test2","address":"test2"}]    
      },
      {
        "id": 9,
        "status": "YELLOW",
        "Shop":"ABC",
        "ownerDetails":[ {"name":"test1","address":"test1"}]
      },
      {
        "id": 10,
        "status": "GREEN",
        "Shop":"EFG",
        "ownerDetails":[ {"name":"test3","address":"test3"}]
      },
    {
        "id": 11,
        "status": "GREEN",
        "Shop":"EFG",
        "ownerDetails":[ ]
      }
    ];
        
        const itemsWithCount = items.map(item => ({
          ...item,
          Count: items.filter(({ status, Shop }) => item.status === status && item.Shop === Shop).length
        }));
    
    For each item of your array, you keep the current value of the item (the `...item`) and you add a `Count` property, that will get the count for this item by filtering the array to keep only the item that have the same status and shop and you get the length of that array.
    

    【讨论】:

    • 当我尝试再添加一张支票时,它不起作用。请看jsfiddle.net/wL46so8a
    • 您需要首先了解上述解决方案的工作原理,以便增强/扩展它以处理另一个名为 ownerDetails 的嵌套子数组。简单地将"name"{ status, Shop } 一起添加到解构中不会将name 从数组ownerDetails 中获取到变量name 中。使用ownerDetails 解构的正确方法可能是这样的:{ status, Shop , ownerDetails: [{ name }]}。同样,这只会从索引 0 处的对象中选择 name。如果 ownerDetails 数组中有更多元素 - 它会忽略这些。
    • 当“ownerDetails”:[]为空数组时,出现以下错误无法读取未定义的属性(读取“名称”)。jsfiddle.net/8qgtsaz6/1
    • 这是因为您正在尝试读取空数组的第一项,因此您必须首先检查数组是否为空:const itemsWithCount = items.map(item => ({ ...item, Count: items.filter(({ status, Shop ,ownerDetails: [{ name }]}) => item.status === status && item.Shop === Shop && item.ownerDetails.length && item.ownerDetails[0].name === name).length }));
    • 您的代码不起作用,但在 ownerDetails 中仍然出现相同的错误:[{ name }]
    猜你喜欢
    • 2016-07-21
    • 2015-07-04
    • 2021-10-20
    • 2016-11-16
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多