Разбор JSON для создания 2D массива в JQuery - PullRequest
0 голосов
/ 26 сентября 2019

Ниже приведен массив JSON, который я хочу преобразовать в двумерный массив с помощью jquery.В указанном формате JSON мне нужно сгруппировать элементы по их jobNumber и activityName.А также внутренний массив должен быть создан на основе item.

[
{
"vehicleHistoryList": [
  {
    "jobNumber": "X9001027",
    "activityName": "5K SERVICE",
    "item": "Labour",
    "description": "Vincent Esmas",
  },
  {
    "jobNumber": "X9001027",
    "activityName": "5K SERVICE",
    "item": "Material",
    "description": "OIL FILTER COROLLA",
  },
  {
    "jobNumber": "X9001027",
    "activityName": "5K SERVICE",
    "material": "Material",
    "description": "10W40 HELIX HX7 ENGINE OIL - SHELL (AUTO EXPRESS)",
  },
  {
    "jobNumber": "X9001124",
    "activityName": "PERIODIC CHECK UP",
    "item": "Material",
    "description": "TERMINAL ASSY INNOVA",
  },
  {
    "jobNumber": "X9001124",
    "activityName": "BATTERY TERMINALS",
    "item": "Labour",
    "description": "Muslim Shah Abdullah Shah",
  },
  {
    "jobNumber": "X9002578",
    "activityName": "5K SERVICE",
    "item": "Material",
    "description": "RIM (ALLOY )FOR YARIS 2016",
  },
  {
    "jobNumber": "X9002578",
    "activityName": "5K SERVICE",
    "item": "Material",
    "description": "TYRE 185/60 R15-MAXXIS",
  },
  {
    "jobNumber": "X9002578",
    "activityName": "5K SERVICE",
    "item": "Labour",
    "description": "Muhammad Akbar Hussain Shah",
  },
  {
    "jobNumber": "X9002578",
    "activityName": "PERIODIC CHECK UP",
    "item": "Material",
    "description": "RIM (ALLOY )FOR YARIS 2016",
  },
  {
    "jobNumber": "X9002578",
    "activityName": "PERIODIC CHECK UP",
    "item": "Labour",
    "description": "Muhammad Akbar Hussain Shah",
  },
  {
    "jobNumber": "X9002578",
    "activityName": "PERIODIC CHECK UP",
    "item": "Labour",
    "description": "Junaid Ali",
  }
]
}
]

Если значение item равно Material, то к значению description необходимо добавитьузел массива материала.
Если значение item равно Labour, то значение description необходимо добавить в узел массива труда.

Ниже приведен необходимый формат .

[
 {
    "vehicleHistoryList": [
      {
        "jobNumber": "X9001027",
        "activities": [
            {
                "activityName": "5K SERVICE",
                "material":[
                    {"OIL FILTER COROLLA"},{"10W40 HELIX HX7 ENGINE OIL - SHELL (AUTO EXPRESS)"}
                ],
                "labours":[
                    {"Vincent"}
                ]
            }
        ]
      },
      {
        "jobNumber": "X9001124",
        "activities": [
            {
                "activityName": "PERIODIC CHECK UP",
                "material":[
                    {"TERMINAL ASSY INNOVA"}
                ],
                "labours":[
                    {"Muslim Shah"}
                ]
            }
        ]
      },
      {
        "jobNumber": "X9002578",
        "activities": [
            {
                "activityName": "5K SERVICE",
                "material":[
                    {"RIM (ALLOY )FOR YARIS 2016"},{"TYRE 185/60 R15-MAXXIS"}
                ],
                "labours":[
                    {"Muhammad Akbar"},{"Hussain Shah"}
                ]
            },
            {
                "activityName": "PERIODIC CHECK UP",
                "material":[
                    {"RIM (ALLOY )"}
                ],
                "labours":[
                    {"Muhammad Hussain"},{"Junaid Ali"}
                ]
            }
        ]
      }
    ]
  }
]  

ПРИМЕЧАНИЕ. Для одного и того же номера задания может быть одно и то же имя.

Ниже приведен код, который я использовал:

var jobNum = []
var jobList = []
var activityName = []
var activityList = []

for(var i=0; i<vehicleHistoryList.length;i++) {
    if(jobNum.indexOf(vehicleHistoryList[i].jobNumber)==-1) {
        jobNum.push(vehicleHistoryList[i].jobNumber)
        jobList.push({jobNum:vehicleHistoryList[i].jobNumber,activities:[]})

        if(activityName.indexOf(vehicleHistoryList[i].activityName)==-1) {
            activityName.push(vehicleHistoryList[i].activityName)
            activityList.push({jobNum:vehicleHistoryList[i].jobNumber,activityName:vehicleHistoryList[i].activityName,material:[],labour:[]})

            var index = activityList.map(function (img) { return img.activityName; }).indexOf(vehicleHistoryList[i].activityName);
            if(vehicleHistoryList[i].material =="Material") {
                activityList[index].material.push(vehicleHistoryList[i].description);
            } else {
                activityList[index].labour.push(vehicleHistoryList[i].description);
            }
        } else {
            var index = activityList.map(function (img) { return img.activityName; }).indexOf(vehicleHistoryList[i].activityName);

            if(vehicleHistoryList[i].material =="Material") {
                activityList[index].material.push(vehicleHistoryList[i].description);
            } else {
                activityList[index].labour.push(vehicleHistoryList[i].description);
            }
        }
    } else {
        var index = jobList.map(function (img) { return img.jobNum; }).indexOf(vehicleHistoryList[i].jobNumber);
        console.log(index)

        if(activityName.indexOf(vehicleHistoryList[i].activityName)==-1) {
            activityName.push(vehicleHistoryList[i].activityName)
            activityList.push({jobNum:vehicleHistoryList[i].jobNumber,activityName:vehicleHistoryList[i].activityName,material:[],labour:[]})

            var index = activityList.map(function (img) { return img.activityName; }).indexOf(vehicleHistoryList[i].activityName);
            if(vehicleHistoryList[i].material =="Material") {
                activityList[index].material.push(vehicleHistoryList[i].description);
            } else {
                activityList[index].labour.push(vehicleHistoryList[i].description);
            }
        } else {
            var index = activityList.map(function (img) { return img.activityName; }).indexOf(vehicleHistoryList[i].activityName);

            if(vehicleHistoryList[i].material =="Material") {
                activityList[index].material.push(vehicleHistoryList[i].description);
            } else {
                activityList[index].labour.push(vehicleHistoryList[i].description);
            }
        }

    }
}   

Проблема, с которой я здесь сталкиваюсь, заключается в том, что, если одно и то же ActivityName входит в другое заданиеNumber, все соответствующие трудозатраты и материал добавляются в один и тот же узел.

Пожалуйста, помогите мне решить эту проблему ивсе ваши ответы будут оценены.Спасибо

1 Ответ

1 голос
/ 26 сентября 2019

Это в основном двухуровневая операция индексации.Если вы нашли работу уже в своем результате, добавьте ее, в противном случае создайте ее.То же самое для действия.

Просто с использованием стандартных методов массива:

const [{vehicleHistoryList}] = data;

const result = vehicleHistoryList.reduce((jobs, v) => {
  let job = jobs.find(({jobNumber}) => jobNumber === v.jobNumber);

  if (!job) {
    job = {jobNumber: v.jobNumber, activities: []};
    jobs.push(job);
  }

  let activity = job.activities.find(({activityName}) => activityName === v.activityName);

  if (!activity) {
    activity = {
      activityName: v.activityName,
      materials: [],
      labours: []
    };
    job.activities.push(activity);
  }  

  if (v.item === 'Material') activity.materials.push(v.description);
  if (v.item === 'Labour') activity.labours.push(v.description);

  return jobs;
}, []);

Полный фрагмент:

const data = [{
  "vehicleHistoryList": [{
      "jobNumber": "X9001027",
      "activityName": "5K SERVICE",
      "item": "Labour",
      "description": "Vincent Esmas",
    },
    {
      "jobNumber": "X9001027",
      "activityName": "5K SERVICE",
      "item": "Material",
      "description": "OIL FILTER COROLLA",
    },
    {
      "jobNumber": "X9001027",
      "activityName": "5K SERVICE",
      "item": "Material",
      "description": "10W40 HELIX HX7 ENGINE OIL - SHELL (AUTO EXPRESS)",
    },
    {
      "jobNumber": "X9001124",
      "activityName": "PERIODIC CHECK UP",
      "item": "Material",
      "description": "TERMINAL ASSY INNOVA",
    },
    {
      "jobNumber": "X9001124",
      "activityName": "BATTERY TERMINALS",
      "item": "Labour",
      "description": "Muslim Shah Abdullah Shah",
    },
    {
      "jobNumber": "X9002578",
      "activityName": "5K SERVICE",
      "item": "Material",
      "description": "RIM (ALLOY )FOR YARIS 2016",
    },
    {
      "jobNumber": "X9002578",
      "activityName": "5K SERVICE",
      "item": "Material",
      "description": "TYRE 185/60 R15-MAXXIS",
    },
    {
      "jobNumber": "X9002578",
      "activityName": "5K SERVICE",
      "item": "Labour",
      "description": "Muhammad Akbar Hussain Shah",
    },
    {
      "jobNumber": "X9002578",
      "activityName": "PERIODIC CHECK UP",
      "item": "Material",
      "description": "RIM (ALLOY )FOR YARIS 2016",
    },
    {
      "jobNumber": "X9002578",
      "activityName": "PERIODIC CHECK UP",
      "item": "Labour",
      "description": "Muhammad Akbar Hussain Shah",
    },
    {
      "jobNumber": "X9002578",
      "activityName": "PERIODIC CHECK UP",
      "item": "Labour",
      "description": "Junaid Ali",
    }
  ]
}];

const [{vehicleHistoryList}] = data;

const result = vehicleHistoryList.reduce((jobs, v) => {
  let job = jobs.find(({jobNumber}) => jobNumber === v.jobNumber);
  
  if (!job) {
    job = {jobNumber: v.jobNumber, activities: []};
    jobs.push(job);
  }
  
  let activity = job.activities.find(({activityName}) => activityName === v.activityName);
  
  if (!activity) {
    activity = {
      activityName: v.activityName,
      materials: [],
      labours: []
    };
    job.activities.push(activity);
  }  
  
  if (v.item === 'Material') activity.materials.push(v.description);
  if (v.item === 'Labour') activity.labours.push(v.description);
  
  return jobs;
}, []);

console.log([{vehicleHistoryList: result}]);
...