Как оптимизировать синтаксический анализ json из одной структуры в другую с помощью javascript?

#javascript #typescript #ecmascript-6

#javascript #typescript #ecmascript-6

Вопрос:

У меня ниже json

 let result = [
    {
        "category": "Social Media",
        "category_id": 6,
        "sub_category": "Facebook",
        "sub_category_id": 5
    },
    {
        "category": "Social Media",
        "category_id": 6,
        "sub_category": "Instagram",
        "sub_category_id": 7
    },
    {
        "category": "Tech",
        "category_id": 3,
        "sub_category": "Angular",
        "sub_category_id": 1
    },
    {
        "category": "Tech",
        "category_id": 3,
        "sub_category": "Javascript",
        "sub_category_id": 6
    }
]
  

Я пытаюсь активировать ниже

 [
  {
    "category": "Social Media",
    "category_id": 6,
    "sub_category": [
      {
        "sub_category": "Instagram",
        "sub_catgory_id": 7
      },
      {
        "sub_category": "Facebook",
        "sub_catgory_id": 5
      }
    ]
  },
  {
    "category": "Tech",
    "category_id": 3,
    "sub_category": [
      {
        "sub_category": "Angular",
        "sub_catgory_id": 1
      },
      {
        "sub_category": "Javascript",
        "sub_catgory_id": 6
      }
    ]
  }
]
  

Приведенный ниже код, который я пробовал. Кто-нибудь может помочь мне определить, где я делаю неправильно?

 let result = [{
    "category": "Social Media",
    "category_id": 6,
    "sub_category": "Facebook",
    "sub_category_id": 5
  },
  {
    "category": "Social Media",
    "category_id": 6,
    "sub_category": "Instagram",
    "sub_category_id": 7
  },
  {
    "category": "Tech",
    "category_id": 3,
    "sub_category": "Angular",
    "sub_category_id": 1
  },
  {
    "category": "Tech",
    "category_id": 3,
    "sub_category": "Javascript",
    "sub_category_id": 6
  }
];

const dataArr = [];
result.forEach((value, key) => {
  let catgeory = {
    category: value.category,
    category_id: value.category_id,
    sub_category: []
  };

  catgeory.sub_category.push({
    sub_category: value.sub_category,
    sub_category_id: value.sub_category_id
  })

  dataArr.push(catgeory);
});

console.log(dataArr);  

Комментарии:

1. Это не имеет ничего общего с JSON или синтаксическим анализом. У вас есть массив объектов, и вы хотите его реструктурировать.

Ответ №1:

Объяснение в комментариях.

 const data = {}

let result = [{"category":"Social Media","category_id":6,"sub_category":"Facebook","sub_category_id":5},{"category":"Social Media","category_id":6,"sub_category":"Instagram","sub_category_id":7},{"category":"Tech","category_id":3,"sub_category":"Angular","sub_category_id":1},{"category":"Tech","category_id":3,"sub_category":"Javascript","sub_category_id":6}];

// loop over each records
result.forEach((value) => {
  // data will be object with key as category and value as category, category_id amp; sub_category array.
  // get data[value.category], if not exist then create new object and assign.
  data[value.category] = data[value.category] || {
    category: value.category,
    category_id: value.category_id,
    sub_category: []
  };
  // push sub_category values.
  data[value.category].sub_category.push({
    sub_category: value.sub_category,
    sub_category_id: value.sub_category_id
  });
});

// we need array of values only so use Object.values(data)
let dataArr = Object.values(data);
console.log(dataArr);  

Ответ №2:

 let result = [{
    "category": "Social Media",
    "category_id": 6,
    "sub_category": "Facebook",
    "sub_category_id": 5
},
{
    "category": "Social Media",
    "category_id": 6,
    "sub_category": "Instagram",
    "sub_category_id": 7
},
{
    "category": "Tech",
    "category_id": 3,
    "sub_category": "Angular",
    "sub_category_id": 1
},
{
    "category": "Tech",
    "category_id": 3,
    "sub_category": "Javascript",
    "sub_category_id": 6
}];

console.log(result.reduce((res,el) => {
  const p = res.find(({category_id}) => category_id == el.category_id);
  if(p) {
    p.sub_category.push({
      sub_category: el.sub_category, 
      sub_category_id: el.sub_category_id
    });
  } else {
    res.push({
       category: el.category,
       category_id: el.category_id,
       sub_category: [{
         sub_category: el.sub_category, 
         sub_category_id: el.sub_category_id
       }]
    })
  }
  return res;
}, []));  

Ответ №3:

Вы создаете новую category с каждой итерацией, тогда как сначала вы должны попытаться проверить, существует ли она уже:

 let catgeory = dataArr.find(item => item.category_id === value.category_id);
  

 let result = [
    {
        "category": "Social Media",
        "category_id": 6,
        "sub_category": "Facebook",
        "sub_category_id": 5
    },
    {
        "category": "Social Media",
        "category_id": 6,
        "sub_category": "Instagram",
        "sub_category_id": 7
    },
    {
        "category": "Tech",
        "category_id": 3,
        "sub_category": "Angular",
        "sub_category_id": 1
    },
    {
        "category": "Tech",
        "category_id": 3,
        "sub_category": "Javascript",
        "sub_category_id": 6
    }
]

const dataArr = [];
result.forEach((value, key) => {
    let category = dataArr.find(item => item.category_id === value.category_id);
    
    if(!category){
         category =  {
            category: value.category,
            category_id: value.category_id,
            sub_category: []
      };

      dataArr.push(category);
    }

    category.sub_category.push(
        {
            sub_category: value.sub_category,
            sub_category_id: value.sub_category_id
        }
    )
});

console.log(dataArr);  

Ответ №4:

Некоторые ответы выполняют поиск внутри цикла, который привел бы к O (N ^ 2) и, следовательно, занял бы больше времени по мере увеличения списка.

Ответ от Karan — это то, что я собирался опубликовать, поскольку это было бы наиболее оптимально с O (N) и было бы наиболее оптимальным, поскольку алгоритму просто нужно один раз пробежаться по списку.