Converting Flat array to json in javascript - javascript

I have an array of conversation between two entities, each distinguished based on parent and level. Every request will be followed by a response object. The sample input structure is like below
[
{ "message": "one", "messageSequence": 0, "level": 1, "Parent": "", "messageType": "request" },
{ "message": "two", "messageType": "response", "messageSequence": 1 },
{ "message": "three-1 (3.1)", "messageSequence": 2, "level": 2, "Parent": 1, "messageType": "request" },
{ "message": "four", "messageType": "response", "messageSequence": 3 },
{ "message": "five-1 (5.1)", "messageSequence": 4, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "six", "messageType": "response", "messageSequence": 5 },
{ "message": "five-2 (5.2)", "messageSequence": 6, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "seven", "messageType": "response", "messageSequence": 7 },
{ "message": "three-2 (3.2)", "messageSequence": 8, "level": 2, "Parent": 1, "messageType": "request" },
{ "message": "eight", "messageType": "response", "messageSequence": 9 },
{ "message": "nine-1 (9.1)", "messageSequence": 10, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "ten", "messageType": "response", "messageSequence": 11 },
{ "message": "nine-2 (9.2) ", "messageSequence": 12, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "eleven", "messageType": "response", "messageSequence": 13 }
]
I am trying to generate a json based on request and its corresponding response. Below is the method which I am using to achieve it
var prevLevel;
var lastUserItem = 0;
function convertToJson(array) {
var map = {};
for (var i = 0; i < array.length; i++) {
var obj = array[i];
if (array[i].messageType == "request")
obj.request = [];
else
obj.response = {};
if (obj.level) {
prevLevel = obj.level
map[obj.level] = obj;
var parent = obj.Parent || '-';
if (!map[parent]) {
map[parent] = {
request: []
};
}
delete obj.Parent;
delete obj.level;
delete obj.messageType;
delete obj.messageSequence;
map[parent].request.push(obj);
lastUserItem = map[parent].request.length - 1;
} else {
delete obj.Parent;
delete obj.level;
delete obj.messageType;
delete obj.messageSequence;
if (map[prevLevel].request && map[prevLevel].request.length > 0) {
map[prevLevel].request[lastUserItem].response = {};
map[prevLevel].request[lastUserItem].response = obj;
} else {
map[prevLevel].response = {};
map[prevLevel].response = obj;
}
}
}
return map['-'].request;
}
var r = convertToJson(messages);
console.log(JSON.stringify(r));
The response which I am getting is not structured based on the request entity.
Response from the above method
[
{
"message": "one",
"request": [
{
"message": "three-1 (3.1)",
"request": [
{
"message": "five-1 (5.1)",
"request": [],
"response":
{
"message": "six",
"response":
{}
}
},
{
"message": "five-2 (5.2)",
"request": [],
"response":
{
"message": "seven",
"response":
{}
}
}],
"response":
{
"message": "four",
"response":
{}
}
},
{
"message": "three-2 (3.2)",
"request": [
{
"message": "nine-1 (9.1)",
"request": [],
"response":
{
"message": "ten",
"response":
{}
}
},
{
"message": "nine-2 (9.2) ",
"request": [],
"response":
{
"message": "eleven",
"response":
{}
}
}],
"response":
{
"message": "eight",
"response":
{}
}
}],
"response":
{
"message": "two",
"response":
{}
}
}]
The Response objects are getting seperated. The expected json output is like below
{
"request": [{
"message": "one",
"response": {
"message": "two"
"request": [{
"message": "three-1 (3.1)",
"response": {
"message": "four"
"request": [{
"message": "five-1 (5.1)",
"response": {
"message": "six"
}
},
{
"message": "five-2 (5.2)",
"response": {
"message": "seven"
}
}
]
}
},
{
"message": "three-2 (3.2)",
"response": {
"message": "eight",
"request": [{
"message": "nine-1 (9.1)",
"response": {
"message": "ten"
}
},
{
"message": "nine-2 (9.2) ",
"response": {
"message": "eleven"
}
}
]
}
}
]
}
}]
}
Please suggest where I am going wrong. Anything to change in the input structure to get the desired output.
https://jsfiddle.net/49qLhL8g/4/

If the 'response' type is always directly coming after 'request', then you could build a new object with a look ahead to the next object and insert this message into the new object as result.
This proposal uses an array for the level reference and updates the levels in that array and as well as in the result.
var data = [{ message: "one", messageSequence: 0, level: 1, Parent: "", messageType: "request" }, { message: "two", messageType: "response", messageSequence: 1 }, { message: "three-1 (3.1)", messageSequence: 2, level: 2, Parent: 1, messageType: "request" }, { message: "four", messageType: "response", messageSequence: 3 }, { message: "five-1 (5.1)", messageSequence: 4, level: 3, Parent: 2, messageType: "request" }, { message: "six", messageType: "response", messageSequence: 5 }, { message: "five-2 (5.2)", messageSequence: 6, level: 3, Parent: 2, messageType: "request" }, { message: "seven", messageType: "response", messageSequence: 7 }, { message: "three-2 (3.2)", messageSequence: 8, level: 2, Parent: 1, messageType: "request" }, { message: "eight", messageType: "response", messageSequence: 9 }, { message: "nine-1 (9.1)", messageSequence: 10, level: 3, Parent: 2, messageType: "request" }, { message: "ten", messageType: "response", messageSequence: 11 }, { message: "nine-2 (9.2) ", messageSequence: 12, level: 3, Parent: 2, messageType: "request" }, { message: "eleven", messageType: "response", messageSequence: 13 }],
result = [],
levels = [result];
data.forEach(function (o, i, a) {
var level = o.level - 1, temp;
if (o.messageType !== 'request') {
return;
}
temp = { message: o.message, response: { message: a[i + 1].message, request: [] } };
levels[level + 1] = temp.response.request;
levels[level].push(temp);
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

I tried to do it using lodash in a very complex way as below .
var _lodash = require('lodash');
var arrayTwo = [
{ "message": "one", "messageSequence": 0, "level": 1, "Parent": "", "messageType": "request" },
{ "message": "two", "messageType": "response", "messageSequence": 1, "Parent": 0 },
{ "message": "three-1 (3.1)", "messageSequence": 2, "level": 2, "Parent": 1, "messageType": "request" },
{ "message": "four", "messageType": "response", "messageSequence": 3, "Parent": 2 },
{ "message": "five-1 (5.1)", "messageSequence": 4, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "six", "messageType": "response", "messageSequence": 5, "Parent": 3 },
{ "message": "five-2 (5.2)", "messageSequence": 6, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "seven", "messageType": "response", "messageSequence": 7, "Parent": 3 },
{ "message": "seven-1 (7.1)", "messageSequence": 8, "level": 4, "Parent": 3, "messageType": "request" },
{ "message": "seven-2 (7.2)", "messageType": "response", "messageSequence": 9, "Parent": 4 },
{ "message": "three-2 (3.2)", "messageSequence": 10, "level": 2, "Parent": 1, "messageType": "request" },
{ "message": "eight", "messageType": "response", "messageSequence": 11, "Parent": 2 },
{ "message": "nine-1 (9.1)", "messageSequence": 12, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "ten", "messageType": "response", "messageSequence": 13, "Parent": 3 },
{ "message": "nine-2 (9.2) ", "messageSequence": 14, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "eleven", "messageType": "response", "messageSequence": 15, "Parent": 3 }
];
var finalObj = {};
for (var i = 0; i < arrayTwo.length; i++) {
if (arrayTwo[i].messageType == "request") {
findAndAppendToRequest(arrayTwo[i]);
} else {
findAndAppendToResponse(arrayTwo[i]);
}
}
console.log(JSON.stringify(finalObj));
function findAndAppendToResponse(item) {
var parent = item.Parent;
var res = findBotNode();
var dt = _lodash.get(finalObj, res);
if (dt) {
if (!_lodash.has(finalObj, res + ".response")) {
_lodash.set(finalObj, res + ".response", {});
}
var data = {};
data.message = item.message;
_lodash.set(finalObj, res + ".response", data);
}
function findBotNode() {
var t = "";
if (parent == 0) {
t = 'request[' + 0 + ']';
} else {
for (var i = 0; i < parent; i++) {
if (!t) {
t = 'request[' + i + ']';
} else {
var temp = t + '.response.request[' + i + ']';
var cnt = 1;
while (!checkIfExists(temp)) {
temp = "";
var val = i - cnt;
temp = t + '.response.request[' + val + ']';
cnt++;
}
t = temp;
}
}
}
return t;
}
}
function checkIfExists(val) {
return _lodash.get(finalObj, val);
}
function findAndAppendToRequest(item) {
var msg = {};
msg.message = item.message;
if (!finalObj.request) {
finalObj.request = [];
finalObj.request.push(msg);
} else {
var parent = item.Parent;
var res = traverseNode();
var dt = _lodash.get(finalObj, res);
if (dt) {
if (!_lodash.has(finalObj, res + ".request")) {
_lodash.set(finalObj, res + ".request", []);
}
var ob = _lodash.get(finalObj, res + ".request");
ob.push(msg);
_lodash.set(finalObj, res + ".request", ob);
}
function traverseNode() {
var t = "";
for (var i = 0; i < parent; i++) {
if (!t) {
t = 'request[' + i + '].response';
} else {
var temp = t + '.request[' + i + '].response';
var cnt = 1;
while (!checkIfExists(temp)) {
temp = "";
var val = i - cnt;
temp = t + '.request[' + val + '].response';
cnt++;
}
t = temp;
}
}
return t;
}
}
}
Not sure if it work for all scenerios . #Nina Scholz great answer.

Related

Comparing an array with another array plus adding a counter

So I'm reformatting my data and I noticed that my data isn't quite getting restructured the way I want it to. I noticed that my results come back as
[
{
"name": "sites",
"parent": null,
"count": 3
},
{
"name": "group1",
"parent": "sites",
"count": 3
},
{
"name": "bk",
"parent": "group1",
"count": 3
},
{
"name": "sitepages",
"parent": "bk",
"count": 1
},
{
"name": "home.aspx",
"parent": "sitepages",
"count": 1
}
]
It isn't grabbing my "not matches". I've spent so much time looking it over and I'm coming to a blank. It should be
[
{
"name": "sites",
"parent": null,
"count": 3
},
{
"name": "group1",
"parent": "sites",
"count": 3
},
{
"name": "bk",
"parent": "group1",
"count": 3
},
{
"name": "sitepages",
"parent": "bk",
"count": 1
},
{
"name": "home.aspx",
"parent": "sitepages",
"count": 1
},
{
"name": "tester",
"parent": "bk",
"count": 1
},
{
"name": "tester",
"parent": "home.aspx",
"count": 1
},
{
"name": "_layouts",
"parent": "bk",
"count": 1
},
{
"name": "15",
"parent": "_layouts",
"count": 1
},
{
"name": "upload.aspx",
"parent": "15",
"count": 1
},
]
I believe something is missing in my loop.
var testArr = [
{
Author: { Title: "Mitchell" },
BrowserType: "FireFox",
Created: "2017-04-25T16:39:40Z",
pathname: "sites/group1/bk/sitepages/home.aspx"
},
{
Author: { Title: "Pierre" },
BrowserType: "Opera",
Created: "2017-04-25T16:39:40Z",
pathname: "sites/group1/bk/tester/home.aspx"
},
{
Author: { Title: "Mizell" },
BrowserType: "IE",
Created: "2017-04-25T16:47:02Z",
pathname: "sites/group1/bk/_layouts/15/upload.aspx"
}
];
function reduceData(data) {
var root = null;
var newArr = null;
var itemContainer = [];
var masterArr = [];
var filteredArr = [];
data.forEach(function (props, idx) {
//check the last character of the pathname is "/" and removes it
if (props.pathname.charAt(props.pathname.length - 1) === "/") {
props.pathname = props.pathname.substring(0, props.pathname.length - 1);
}
//lowercase the pathname + split into strings
props.pathname = props.pathname.toLowerCase().split("/");
//format the pathname
var lastItem = "";
newArr = props.pathname.reduce(function (acc, props, index) {
if (acc.length === 0) {
acc.push({ name: props, parent: null, count: 1 });
lastItem = props;
} else {
acc.push({ name: props, parent: lastItem, count: 1 });
lastItem = props;
}
return acc;
}, []);
//The first iteration
if (idx === 0) {
itemContainer = newArr;
} else {
for (var i = 0; i < itemContainer.length; i++) {
// Loop for newArr
for (var j = 0; j < newArr.length; j++) {
//compare the element of each and every element from both of the arrays
//console.log(masterArr[i], newArr[j]);
if (
itemContainer[i].name === newArr[j].name &&
itemContainer[i].parent === newArr[j].parent
) {
//Match
masterArr[i] = {
name: itemContainer[i].name,
parent: itemContainer[i].parent,
count: itemContainer[i].count++
};
} else {
//Doesn't Match
masterArr[i] = {
name: itemContainer[i].name,
parent: itemContainer[i].parent,
count: itemContainer[i].count
};
}
}
}
}
});
console.log(masterArr)
}
reduceData(testArr)
ok.. I revamp your code a little..
delete the if else after the //The first iteration, and use this instead..
newArr.forEach((newEl) => {
const matchIdx = masterArr.findIndex((masterEl) => masterEl.name === newEl.name && masterEl.parent === newEl.parent);
if(matchIdx < 0){
masterArr.push(newEl);
}
else {
masterArr[matchIdx].count = masterArr[matchIdx].count + 1;
}
});

get latest date for each day in an array of object?

i have array of object which are sorted based on date/time, I have to form an array of object with latest data from each date?. I'm getting the solution with for loop but I need to use es6 and above, please help me with a better and advanced solution.
var array = [
{
"id": 1,
"date": "2016-01-15T16:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 2,
"date": "2016-01-15T18:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 3,
"date": "2016-01-15T20:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 4,
"date": "2016-01-19T16:18:44.258843Z",
"status": "STD",
"request": 4
},
{
"id": 6,
"date": "2016-01-23T17:18:44.258843Z",
"status": "FOR",
"request": 4
},
{
"id": 5,
"date": "2016-01-23T16:18:44.258843Z",
"status": "FOR",
"request": 4
}]
const list = filter(array, el => (el.date));
latestDate = list[0]?.date.slice(0, 10);
latestResponse.push(res[0]);
for (let i = array.length - 1; i > 0; i--) {
if (this.latestDate !== array[i].date.slice(0, 10)) {
latestDate = (array[i].date).slice(0, 10);
latestResponse.push(res[i]);
}
}
expected Output
var array = [
{
"id": 3,
"date": "2016-01-15T20:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 4,
"date": "2016-01-19T16:18:44.258843Z",
"status": "STD",
"request": 4
},
{
"id": 5,
"date": "2016-01-23T17:18:44.258843Z",
"status": "FOR",
"request": 4
}]
Here is the code, use reduce method.
var array = [
{
"id": 1,
"date": "2016-01-15T16:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 2,
"date": "2016-01-15T18:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 3,
"date": "2016-01-15T20:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 4,
"date": "2016-01-19T16:18:44.258843Z",
"status": "STD",
"request": 4
},
{
"id": 6,
"date": "2016-01-23T17:18:44.258843Z",
"status": "FOR",
"request": 4
},
{
"id": 5,
"date": "2016-01-23T16:18:44.258843Z",
"status": "FOR",
"request": 4
}];
console.clear();
let results = array.reduce((acc: any, cur: any) => {
let curDate = new Date(cur.date);
let curDateStr = curDate.getFullYear() + '-' + (curDate.getMonth() + 1) + '-' + curDate.getDate();
let existDateObj = acc.find(f => f.dStr === curDateStr);
if (existDateObj) {
let existDate = new Date(existDateObj.date);
if (curDate.getTime() > existDate.getTime()) {
acc = acc.filter(f => f.id !== existDateObj.id);
acc.push(Object.assign(cur, { dStr: curDateStr }));
}
} else {
acc.push(Object.assign(cur, { dStr: curDateStr }));
}
return acc;
}, []);
console.log(results);
You can try this. Sort, group, get
array.sort(function(a,b){
return new Date(a.date) - new Date(b.date);
});
var newArray=[];
result = array.reduce(function (r, a) {
r[a.status] = r[a.status] || [];
r[a.status].push(a);
return r;
}, Object.create(null));
for (const n in result) {
newArray.push(result[n].slice(-1))
}
Instead of using multiple array methods/loops, this can be done using a single for of loop as follows,
function getLatestDateInfo(array) {
let obj = {};
for (const item of array) {
var today = new Date(item.date);
var year = today.getFullYear();
var month = today.getMonth() + 1;
var day = today.getDate();
var mainDate = day + "-" + month + "-" + year;
obj = {
...obj,
[mainDate]: { ...item },
}
}
return Object.values(obj);
}
The above solution is based on the assumption that the array of objects are sorted based on date/time, as this is mentioned in the question.
const latestResponse = [];
const list = filter(res, el => (el.date));
let latestDate = moment(list[0]?.date).format("DD/MM/YYYY");
[...res].reverse().filter(el => {
if (latestDate !== moment(el.date).format("DD/MM/YYYY")) {
latestDate = moment(el.date).format("DD/MM/YYYY");
latestResponse.push(el);
}
})
used moment to format the date, and used filter to generate the new array
var array = [
{
"id": 1,
"date": "2016-01-15T16:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 2,
"date": "2016-01-15T18:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 3,
"date": "2016-01-15T20:18:44.258843Z",
"status": "NEW",
"request": 4
},
{
"id": 4,
"date": "2016-01-19T16:18:44.258843Z",
"status": "STD",
"request": 4
},
{
"id": 6,
"date": "2016-01-23T17:18:44.258843Z",
"status": "FOR",
"request": 4
},
{
"id": 5,
"date": "2016-01-23T16:18:44.258843Z",
"status": "FOR",
"request": 4
}];
const sortedLatestArray = array.sort((a, b) => {
if(a.date > b.date) {
return -1;
} else if (a.date === b.date){
return 0;
} else {
return 1;
}
}).filter((item, i, sortedArray) => {
if(i) {
const prevItem = sortedArray[i - 1];
const prevItemDate = prevItem.date.slice(0, 10);
const currentItemDate = item.date.slice(0, 10);
return currentItemDate !== prevItemDate;
}
return true;
}).reverse();
console.log(sortedLatestArray);
Sort array latest to oldest, and then remove duplicated date item by comparing former Item and current Item using filter method, finally reverse array to make result sorted as oldest to latest.
Use forEach and build an object with keys as date. If the same date exist, then replace with latest date-time.
const refine = (arr) => {
const res = {};
arr.forEach((item) => {
const date_str = item.date.split('T')[0];
res[date_str] ??= { ...item };
if (new Date(item.date) > new Date(res[date_str].date)) {
res[date_str].date = item.date;
}
});
return Object.values(res);
};
var array = [
{
id: 1,
date: "2016-01-15T16:18:44.258843Z",
status: "NEW",
request: 4,
},
{
id: 2,
date: "2016-01-15T18:18:44.258843Z",
status: "NEW",
request: 4,
},
{
id: 3,
date: "2016-01-15T20:18:44.258843Z",
status: "NEW",
request: 4,
},
{
id: 4,
date: "2016-01-19T16:18:44.258843Z",
status: "STD",
request: 4,
},
{
id: 6,
date: "2016-01-23T17:18:44.258843Z",
status: "FOR",
request: 4,
},
{
id: 5,
date: "2016-01-23T16:18:44.258843Z",
status: "FOR",
request: 4,
},
];
console.log(refine(array));

Javascript(NodeJs) - Conversion of Arrays and Objects to bulk insert in mysql(Sequelize)

This is my json:
{
"senderName": "ifelse",
"message": "Hi",
"groups": [
{
"id": 14,
"groupname": "Angular",
"contactgroups": [
{
"id": 1,
"contact": {
"id": 1,
"gsm": "123456789"
}
},
{
"id": 3,
"contact": {
"id": 2,
"gsm": "111111111"
}
}],
"select": true
}],
"draftData": {
"contacts": [
]
}
}
How to make the above json into:
[{phoneno: 123456789; sender: ifelse ; message: Hi},{phoneno: 11111111; sender: ifelse ; message: Hi}]
I want to take phoneno data from gsm object key
Which is best method to do this? for or forEach or anyother?
I guess, this is what you want. Use map to convert contactgroups to new array with phoneno.
var data = {
"senderName": "ifelse",
"message": "Hi",
"groups": [{
"id": 14,
"groupname": "Angular",
"contactgroups": [{
"id": 1,
"contact": {
"id": 1,
"gsm": "123456789"
}
},
{
"id": 3,
"contact": {
"id": 2,
"gsm": "111111111"
}
}
],
"select": true
}],
"draftData": {
"contacts": []
}
}
var result = data.groups[0].contactgroups.map(i => {
return {
phoneno: i.contact.gsm,
sender: data.senderName,
message: data.message
}
})
console.log(result);

create new json from existing json using AngularJS or Javascript

Category JSON
I am getting this JSON by accessing API and soring it in $scope.categoryList
[
{
"id": 1,
"name": "Men"
},
{
"id": 2,
"name": "Women"
},
{
"id": 3,
"name": "Kids"
}
]
SubCategory JSON
I am getting this JSON by accessing API and soring it in $scope.subCategoryList
[
{
"id": 1,
"category_id": 1,
"name": "Footwear"
},
{
"id": 2,
"category_id": 2,
"name": "Footwear"
},
{
"id": 3,
"category_id": 1,
"name": "Cloths"
}
]
I need to design this in below format
[
{
"categoryId" : 1,
"categoryName" : "Men",
"subCategory" : [
{
"subCategoryId": 1,
"subCategoryName": "Footwear"
},
{
"subCategoryId": 3,
"subCategoryName": "Cloths"
},
]
},
{
"categoryId" : 2,
"categoryName" : "Women",
"subCategory" : [
{
"subCategoryId": 2,
"subCategoryName": "Footwear"
}
]
},
{
"categoryId" : 3,
"categoryName" : "Kids",
"subCategory" : []
}
]
I have the code but it is not showing perfect data
$scope.catSubCat = []
angular.forEach($scope.subcategoryList, function(subValue, subKey) {
$scope.subCat = {
'subCategoryId' : '',
'subCategoryName' : ''
}
angular.forEach($scope.categoryList, function(catValue, catKey) {
if(subValue.category_id == catValue.id) {
$scope.subCat.subCategoryId = subValue.id;
$scope.subCat.subCategoryName = subValue.name;
$scope.subCategory = {
'categoryId' : '',
'categoryName' : '',
'subCatName' : []
}
$scope.catVal.categoryId = subValue.category_id;
$scope.catVal.categoryName = catValue.name;
$scope.catVal.subCatName.push($scope.subCat);
}
$scope.catSubCat.push($scope.catVal);
});
});
This should do the trick. Not as clean as 31piy's (wow!) but more efficient. (O(N + M) as opposed to O(N * M))
const categoryList = [
{
"id": 1,
"name": "Men"
},
{
"id": 2,
"name": "Women"
},
{
"id": 3,
"name": "Kids"
}
];
const subCategoryList = [
{
"id": 1,
"category_id": 1,
"name": "Footwear"
},
{
"id": 2,
"category_id": 2,
"name": "Footwear"
},
{
"id": 3,
"category_id": 1,
"name": "Cloths"
}
];
const mergeCategoryLists = (categoryList, subCategoryList) => {
// Turn categoryList into an object with categoryId as key
const categoryById = {};
categoryList.forEach((category) => {
categoryById[category.id] = {
categoryName: category.name,
categoryId: category.id,
subCategory: []
};
});
// Add subcategories
subCategoryList.forEach((subCategory) => {
const formattedSubCategory = {
subCategoryId: subCategory.id,
subCategoryName: subCategory.name
};
categoryById[subCategory.category_id].subCategory.push(formattedSubCategory);
});
// Convert categoryById into desired format
return Object.values(categoryById);
};
console.log(mergeCategoryLists(categoryList, subCategoryList));
Check out this logic .
$scope.newArray = angular.copy($scope.categoryList);
$scope.catSubCat = []
angular.forEach($scope.subcategoryList, function(subValue, subKey) {
$scope.subCat = {
'subCategoryId' : '',
'subCategoryName' : ''
}
angular.forEach($scope.newArray, function(catValue, catKey) {
$scope.subCat.subCategoryId = subValue.id;
$scope.subCat.subCategoryName = subValue.name;
if(subValue.category_id == catValue.id) {
if(catValue.subCatName.hasOwnProperty('bye')){
$scope.newArray[catKey].subCatName = [];
$scope.newArray[catKey].subCatName.push($scope.subCat);
}else{
$scope.newArray[catKey].subCatName.push($scope.subCat);
}
}
});
});
Resultant will we in $scope.newArray
You can use Array#map in combination with Array#filter to achieve the desired results:
var categories = [{
"id": 1,
"name": "Men"
},
{
"id": 2,
"name": "Women"
},
{
"id": 3,
"name": "Kids"
}
];
var subcategories = [{
"id": 1,
"category_id": 1,
"name": "Footwear"
},
{
"id": 2,
"category_id": 2,
"name": "Footwear"
},
{
"id": 3,
"category_id": 1,
"name": "Cloths"
}
];
var result = categories.map(cat => {
return {
categoryId: cat.id,
categoryName: cat.name,
subCategory: subcategories
.filter(subc => subc.category_id === cat.id)
.map(subc => {
return {
subCategoryId: subc.id,
subCategoryName: subc.name
};
})
};
});
console.log(result);
var categoryList = [{
"id": 1,
"name": "Men"
}, {
"id": 2,
"name": "Women"
}, {
"id": 3,
"name": "Kids"
}];
var subCategoryList = [{
"id": 1,
"category_id": 1,
"name": "Footwear"
}, {
"id": 2,
"category_id": 2,
"name": "Footwear"
}, {
"id": 3,
"category_id": 1,
"name": "Cloths"
}];
var finalJson = [];
for (var i = 0; i < categoryList.length; i++) {
var obj = {
categoryId: categoryList[i].id,
categoryName: categoryList[i].name,
subCategory: []
};
var subCat = subCategoryList.filter(function(word) {
return word.category_id === categoryList[i].id;
});
for (var j = 0; j < subCat.length; j++) {
var obj2 = {
subCategoryId: subCat[j].id,
subCategoryName: subCat[j].name
};
obj.subCategory.push(obj2);
}
finalJson.push(obj);
}
console.log(finalJson);
Pure Javascript solution to your question, you can replace with
Angular Syntax then..
Use following code:
$scope.catSubCat = []
angular.forEach($scope.categoryList, function(catValue, catKey) {
var catObj = {
'categoryId' : '',
'categoryName' : '',
'subCatName' : []
}
catObj.categoryId = catValue.id;
catObj.categoryId = catValue.name;
angular.forEach($scope.subcategoryList, function(subValue, subKey) {
if(subValue.category_id == catValue.id) {
var subCatObj = {
'subCategoryId' : '',
'subCategoryName' : ''
}
subCatObj.subCategoryId = subValue.category_id;
subCatObj.subCategoryName = catValue.name;
catObj.subCatName.push(subCatObj);
}
});
$scope.catSubCat.push(catObj);
});

Javascript Array - adding a value to a particular key

var all_area = [];
$.each(data,function(i,v){
$.each(v.areas,function(a,b){
all_area[i]['id'] = b.id;
all_area[i]['name'] = b.name;
});
});
I want an array that has these data:
all_area[0]['id'] = 1;
all_area[0]['name'] = "test";
all_area[1]['id'] = 2;
all_area[1]['name'] = "test123";
My code is not working. I am getting this error:
Uncaught TypeError: Cannot set property 'id' of undefined
This is the sample data that i am getting from my ajax call:
[
{
"name": "Dubai",
"id": "1",
"areas": [
{
"name": "Deira",
"id": 1,
"extra_fee": 0,
"extra_time": 0,
"min_order": 0
},
{
"name": "Bur Dubai",
"id": 2,
"extra_fee": 5,
"extra_time": 10,
"min_order": 100
}
]
},
{
"name": "Abu Dhabi",
"id": "2",
"areas": [
{
"name": "Shahama",
"id": 3,
"extra_fee": 0,
"extra_time": 0,
"min_order": 0
},
{
"name": "City Center",
"id": 4,
"extra_fee": 5,
"extra_time": 10,
"min_order": 100
}
]
}
]
Thanks.
Initialize the object
$.each(v.areas,function(a,b){
all_area[i] = {};
all_area[i]['id'] = b.id;
all_area[i]['name'] = b.name;
});
OR,
$.each(v.areas,function(a,b){
all_area[i] = {
id : b.id,
name : b.name
};
});

Categories