javascript - 使用 javascript 根据状态和商店计算对象?

标签 javascript arrays json angularjs

我有以下 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') in console

代码:

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)

最佳答案

undefined object 的解构

/**
 * 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 } = {}] = [];

访问 undefined object 的属性

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

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

  1. 验证item.ownerDetails中至少有一个元素;
  2. 验证名称属性存在于第一个元素上;

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

工作示例

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' }
]

关于javascript - 使用 javascript 根据状态和商店计算对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72084738/

相关文章:

javascript - 如何创建圆环饼图的内边框?

java - 将主要参数传递给方法

java - Jersey 内容类型定制

java - 无法从json文件打印json数组的所有键和值

json - Rswag 模式不会因数组中对象的无效属性而失败

javascript - 清除浏览器缓存以加载重命名的文件

javascript - 在 React 中使用 onChange 设置状态导致 Canvas 为空

javascript - 如何一次将一个项目添加(推送)到数组中(循环遍历数组)

javascript - slider 的样式在 IE 中无法正常工作

php - php json 输出中 undefined variable