Re formating a json - javascript

I'm getting this to work with:
[
{
"questionId":1,
"level":1,
"difficultyLevel":1.1,
"stage":1,
"item #":1,
"targetWord":"example1",
"category":"hard"
},
{
"questionId":2,
"level":1,
"difficultyLevel":1.1,
"stage":1,
"item #":2,
"targetWord":"example2",
"category":"hard"
},
{
"questionId":3,
"level":1,
"difficultyLeveluest":1.1,
"stage":1,
"item #":3,
"targetWord":"example3",
"category":"soft"
},
{
"questionId":4,
"level":1,
"difficultyLevel":"1.1b",
"stage":1,
"item #":4,
"targetWord":"example4",
"category":"hard"
},
{
"questionId":5,
"level":1,
"difficultyLevel":"1.1b",
"stage":1,
"item #":5,
"targetWord":"example5",
"category":"soft"
},
{
"questionId":6,
"level":1,
"difficultyLevel":"1.1b",
"stage":1,
"item #":6,
"targetWord":"example6",
"category":"hard"
},
{
"questionId":7,
"level":1,
"difficultyLevel":1.2,
"stage":1,
"item #":7,
"targetWord":"example7",
"category":"hard"
},
{
"questionId":8,
"level":1,
"difficultyLevel":1.2,
"stage":1,
"item #":8,
"targetWord":"example8",
"category":"soft"
},
{
"questionId":9,
"level":1,
"difficultyLevel":1.2,
"stage":1,
"item #":9,
"targetWord":"example9",
"category":"soft"
},
{
"questionId":10,
"level":1,
"difficultyLevel":"1.2b",
"stage":1,
"item #":1,
"targetWord":"example10",
"category":"hard"
},
{
"questionId":11,
"level":1,
"difficultyLevel":"1.2b",
"stage":1,
"item #":2,
"targetWord":"example11",
"category":"hard"
},
{
"questionId":12,
"level":1,
"difficultyLevel":"1.2b",
"stage":1,
"item #":3,
"targetWord":"example12",
"category":"soft"
}
]
I need to reformat it and separate it by level, I think it should make sense that it looks something like this:
levels{
1{
difficulty{
1.1{
questions[
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
]
}
1.1b{
questions[
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
]
}
}
}
2{
difficulty{
1.2{
questions[
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
]
}
1.2b{
questions[
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
{
questionId
targetWord
item
}
]
}
}
}
}
But I don't really know how to do it... here is what i could do:
{
levels: {
'1': {
dificulty: '1.1b'
questionId: 6,
targetWord: 'example6',
},
'2': {
dificulty: '1.2b'
questionId: 12,
targetWord: 'example12',
}
}
}
The snippet above is achieved by:
const setLevels = (levelMapData) => {
const levelMap = {};
levelMapData
.forEach(({ level, questionId, targetWord, dificultyLevel }) => {
levelMap[level] = {
dificultyLevel,
questionId,
targetWord,
};
});
return levelMap;
}
module.exports = async ([levelMapData]) => {
const levels = setLevels(levelMapData);
const curriculum = {
levels,
};
return curriculum;
};
How can I make it format properly? Please help. And thank you very much in advance.

You need to repeat with difficultyLevel what you do with level, but at a deeper level in the target data structure. You can use the ??= operator to create the properties that you need but don't exist yet on the fly, and and so drill down to the place where a push must be executed to add the question object:
function tree(levelMapData) {
const levelMap = {};
for (const { level, difficultyLevel, questionId, targetWord, "item #": item } of levelMapData) {
((levelMap[level] ??= {})[difficultyLevel] ??= []).push({
questionId, targetWord, item
});
}
return levelMap;
}
const levelMapData = [{"questionId":1,"level":1,"difficultyLevel":1.1,"stage":1,"item #":1,"targetWord":"example1","category":"hard"},{"questionId":2,"level":1,"difficultyLevel":1.1,"stage":1,"item #":2,"targetWord":"example2","category":"hard"},{"questionId":3,"level":1,"difficultyLeveluest":1.1,"stage":1,"item #":3,"targetWord":"example3","category":"soft"},{"questionId":4,"level":1,"difficultyLevel":"1.1b","stage":1,"item #":4,"targetWord":"example4","category":"hard"},{"questionId":5,"level":1,"difficultyLevel":"1.1b","stage":1,"item #":5,"targetWord":"example5","category":"soft"},{"questionId":6,"level":1,"difficultyLevel":"1.1b","stage":1,"item #":6,"targetWord":"example6","category":"hard"},{"questionId":7,"level":1,"difficultyLevel":1.2,"stage":1,"item #":7,"targetWord":"example7","category":"hard"},{"questionId":8,"level":1,"difficultyLevel":1.2,"stage":1,"item #":8,"targetWord":"example8","category":"soft"},{"questionId":9,"level":1,"difficultyLevel":1.2,"stage":1,"item #":9,"targetWord":"example9","category":"soft"},{"questionId":10,"level":1,"difficultyLevel":"1.2b","stage":1,"item #":1,"targetWord":"example10","category":"hard"},{"questionId":11,"level":1,"difficultyLevel":"1.2b","stage":1,"item #":2,"targetWord":"example11","category":"hard"},{"questionId":12,"level":1,"difficultyLevel":"1.2b","stage":1,"item #":3,"targetWord":"example12","category":"soft"}];
const result = tree(levelMapData);
console.log(result);

Related

Javascript/Jquery - Create array format based on JSON response

Used below JS code to get JSON response from endpoint URL. Response value returns correctly like below JSON format.
From this JSON format, i need to extract and display in array format for DATALAYER. But, below code getting output of last time instead of all JSON response items to show.
Format required:
newArray [
{
codePlan: "SSS0111",
title: "Title 1"
},
{
codePlan: "",
title: "Title 2"
},
{
codePlan: "SSS0888,CCC0222,EEE0001,DDD0009",
title: "Title 3"
}
]
But it get last item only and displays like this.
newArray [
{
codePlan: "SSS0891",
title: "Title 5"
}
]
var endpointUrl = '/data/codelisting.json';
$.get(endpointUrl, function (response) {
$.each(response.data, function (i, item) {
var dataLayerObject = {};
var newArray = [
{
codePlan: item.codePlan,
title: item.title
}
];
dataLayerObject = {
arrayParent: {
newArray : [...newArray]
}
};
DTM.setDataLayer(dataLayerObject);
});
});
{
"total": 5,
"data":[
{
"title":"Title 1",
"description":"description 1"
"codePlan":[
"SSS0111"
]
},
{
"title":"Title 2",
"description":"description 2"
"codePlan":[]
},
{
"title":"Title 3",
"description":"description 3"
"codePlan":[
"SSS0888",
"CCC0222",
"EEE0001",
"DDD0009"
]
},
{
"title":"Title 4",
"description":"description 4"
"codePlan":[
"SSS0897"
]
},
{
"title":"Title 5",
"description":"description 5"
"codePlan":[
"SSS0891"
]
}
]
}
The problem with var newArray = [ it updates the newArray value with a new value each time in a loop .. So you need to define it before .each() var newArray = []; and let .each() add a new value to it newArray[i] =
$.get(endpointUrl, function (response) {
var newArray = []; //<<<<<<<<<<< here
$.each(response.data, function (i, item) {
var dataLayerObject = {};
newArray[i] = [ // <<<<<< use newArray[i] here
{
codePlan: item.codePlan,
title: item.title
}
];
dataLayerObject = {
arrayParent: {
newArray : [...newArray]
}
};
DTM.setDataLayer(dataLayerObject);
});
var response = [
{
codePlan: "SSS0111",
title: "Title 1"
},
{
codePlan: "",
title: "Title 2"
},
{
codePlan: "SSS0888,CCC0222,EEE0001,DDD0009",
title: "Title 3"
}
];
var newArray = []
$.each(response , function(i , item){
newArray[i] = [{
codePlan: item.codePlan,
title: item.title
}]
});
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Converting Flat List to Parent Child Tree

I'm trying build a tree from a flat list, and I know I'm missing something that would make this much easier and faster. I've tried several approaches. The latest being the function I've posted below.
The flat list that looks like this:
var input = [
{
"Parent Category": "Agricultural Feed + Seed",
Category: "Agricultural Feed + Seed",
Name: "Agfinity"
},
{
"Parent Category": "Agricultural Feed + Seed",
Category: "Agricultural Feed + Seed",
Name: "Agland Co-op"
},
{
"Parent Category": "Agricultural Feed + Seed",
Category: "Agricultural Equipment",
Name: "Agri Supply"
},
{
"Parent Category": "Agricultural Equipment",
Category: "Tractors",
Name: "Agway"
},
{
"Parent Category": "Agricultural Equipment",
Category: "Tractors",
Name: "Agway2"
},
{
"Parent Category": "Travel",
Category: "Travel",
Name: "Amtrak"
},
{
"Parent Category": "Travel",
Category: "Accessories",
Name: "Bentley Leathers & Luggage"
}
];
From this list I'm trying to build a tree that looks like this:
[
{
"label": "Agricultural Feed + Seed",
"children": [
{
"label": "Agfinfity"
},
{
"label": "Agland Co-op"
},
{
"label": "Agricultural Equipment",
"children": [
{
"label": "Agri Supply"
"children": [
{
"label": "Tractors",
"children": [
{
"label": "Agway"
},
{
"label": "Agway2"
}
]
}
]
}
]
}
]
},
{
"label": "Travel",
"children": [
{
"label": "Amtrak"
},
{
"label": "Acessories",
"children": [
{
"label": "Bentley Leathers & Luggage"
},
}
]
}
];
I have a function like this that almost works, but I know it's not the right approach.
function formatBrandNames(rawBrands) {
let output = [];
for (let i = 0; i < rawBrands.length; i++) {
// Parent Category
if (!output.find(v => v.label === rawBrands[i]["Parent Category"])) {
output.push({
label: rawBrands[i]["Parent Category"],
children: []
});
}
// Category
let parentCat = output.find(v => v.label === rawBrands[i]["Parent Category"]);
if (rawBrands[i]["Category"] === parentCat.label) {
const name = trimBrandNumbers(rawBrands[i]["Name"]);
parentCat.children.push({ label: name });
continue;
}
if (!parentCat.children.find(v => v.label === rawBrands[i]["Category"])) {
parentCat.children.push({ label: rawBrands[i]["Category"], children: [] });
}
// Name
let cat = parentCat.children.find(v => v.label === rawBrands[i]["Category"]);
const name = trimBrandNumbers(rawBrands[i]["Name"]);
cat.children.push({ label: name });
}
return output;
}
Any help or insight on this would be greatly appreciated.
The logic can be simplified to
If the node has no parent category, it is one of the root categories
Find the Parent by it's category, then add the node to the parent's children
If the parent does not exist, create it.
function toTree(nodes) {
const roots = [];
const byCategory = new Map();
for(const { Name: label, ["Parent Category"]: parent, Category: category } of nodes) {
const node = { label, children: [] };
if(byCategory.has(category)) {
byCategory.get(category).children.push(node);
} else {
const categoryObj = {
label: category,
children: [node]
};
byCategory.set(category, categoryObj);
if(parent === category) {
roots.push(categoryObj);
} else if(byCategory.has(parent)) {
byCategory.get(parent).children.push(categoryObj);
} else {
byCategory.set(parent, { label: parent, children: [categoryObj] });
}
}
}
return roots;
}

How to access object value

I have this array of an object, I need to select the 'default_image' or 'label' or 'html' values using loop. But unable to do this.
var panel_array = [{
"Panel":{
"Panel_1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"Panel_2":{
"default_image":"<img src='"+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
"List":{
"l1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"l2":{
"default_image":"<img src='"+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
}]
I tried this and it prints all the values but how to access single value like if i want only 'label' or i want only 'html':
panel_array.map(data => {
for (var items in data) {
for(var dt in data[items]){
var ab = data[items];
for(var xx in ab) {
var ii = ab[xx];
for(var oo in ii){
console.log(ii[oo]);
}
}
}
}
})
Just add an if clause:
var panel_array = [{
"Panel":{
"Panel_1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"Panel_2":{
"default_image":"<img src='/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
"List":{
"l1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"l2":{
"default_image":"<img src='/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
}]
panel_array.map(data => {
for (var items in data) {
for(var dt in data[items]){
var ab = data[items];
for(var xx in ab) {
var ii = ab[xx];
for(var oo in ii){
if (oo == "label" || oo == "html") console.log(ii[oo]);
}
}
}
}
})
You can use forEach of array, Object.keys and Object.values()
const panel_array = [{
"Panel": {
"Panel_1": {
"default_image": "http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label": "Panel List 1",
"html": "<dl class='drop_list1'></dl>"
},
"Panel_2": {
"default_image": "<img src='/prepengine/images/Interactive-items/panel2.png'",
"label": "Panel List 2",
"html": "<dl class='drop_list2'></dl>"
}
},
"List": {
"l1": {
"default_image": "http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label": "Panel List 1",
"html": "<dl class='drop_list1'></dl>"
},
"l2": {
"default_image": "<img src='/prepengine/images/Interactive-items/panel2.png'",
"label": "Panel List 2",
"html": "<dl class='drop_list2'></dl>"
}
},
}];
panel_array.forEach(o => {
Object.keys(o).forEach(key => {
Object.values(o[key]).forEach(item => {
//you can access whatever you need
console.log(item);
});
});
});
let themeUrl = 'MockmyUrl';
let panel_array = [{
"Panel":{
"Panel_1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"Panel_2":{
"default_image":"<img src="+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
"List":{
"l1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"l2":{
"default_image":"<img src='"+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
}];
let images = [];
let lables = [];
let htmls = [];
let output = panel_array.forEach((ele) => {
Object.values(ele).forEach((ele2) => {
Object.values(ele2).forEach((ele3) => {
let {default_image, label, html} = ele3;
images.push(default_image);
lables.push(label);
htmls.push(html);
});
});
});
console.log(images);
console.log('----------------');
console.log(lables);
console.log('----------------');
console.log(htmls);

How to change values in array which meet criteria via JS

I have a big JSON data, this is a small part:
users = [{
"name": "alex",
"id":123,
"surname":"xx",
"status":"activated",
tarriff: {
"id":1,
"name":"free"
}
},
{
"name": "tom",
"id":124,
"surname":"henry",
"status":"activated",
tarriff: {
"id":1,
"name":"free"
}
},
{
"name": "tom",
"id":125,
"surname":"henry",
"status":"archived",
tarriff: {
"id":1,
"name":"free"
}
}]
I need to change value 'activated' to 'deactivated', 'archived' to 'active' in whole array.
I think I need to use for loop, but I don't know how to properly write it.
Use the Array prototype map function :
users = users.map(function(u) {
if (u.status == 'activated') u.status = 'deactivated'
if (u.status == 'archived') u.status = 'active'
return u
})
Update. A faster approach.
var counter, item;
for (counter in users) {
item = users[counter];
if (item.status == 'activated') item.status = 'deactivated'
if (item.status == 'archived') item.status = 'active'
}
You cannot do it faster or more narrow.
Try the following with array's map().
var users = [{
"name": "alex",
"id":123,
"surname":"xx",
"status":"activated",
tarriff: {
"id":1,
"name":"free"
}
},
{
"name": "tom",
"id":124,
"surname":"henry",
"status":"activated",
tarriff: {
"id":1,
"name":"free"
}
},
{
"name": "tom",
"id":125,
"surname":"henry",
"status":"archived",
tarriff: {
"id":1,
"name":"free"
}
}];
var res = users.map(function(item){
if(item.status == 'activated')
item.status = 'deactivated';
if(item.status == 'archived')
item.status = 'active';
return item;
});
console.log(res);
this is a possible way (Array#extras):
function changeUserStatus(status) {
// 'activated' to 'deactivated', 'archived' to 'active'
switch (status) {
case 'activated':
return 'deactivated';
case 'archived':
return 'active';
default:
return status;
}
}
function changeStatus(users) {
return users.map(function(user) {
return Object.assign({}, user, {
status: changeUserStatus(user.status),
});
});
}
var users = [{
"name": "alex",
"id":123,
"surname":"xx",
"status":"activated",
tarriff: {
"id":1,
"name":"free"
}
},
{
"name": "tom",
"id":124,
"surname":"henry",
"status":"activated",
tarriff: {
"id":1,
"name":"free"
}
},
{
"name": "tom",
"id":125,
"surname":"henry",
"status":"archived",
tarriff: {
"id":1,
"name":"free"
}
}];
const edited = changeStatus(users);
console.log('edited', edited);
Do not know if your intentions about to mutate original object or just return a new array of objects. But below code might give you an inspiration.
function changeValue(obj, k, vold, vnew) {
if (obj.hasOwnProperty(k) && obj[k] == vold) {
obj[k] = vnew
}
return obj;
}
then,
users
.map(e => changeValue(e, 'status', 'activated', 'deactivated'))
.map(e => changeValue(e, 'status', 'archived', 'active'));

How can I extract objects several layers deep using the map method?

I'm a trying to access the change order information as seen below to create a list of all the change_order_names. Using the current code I am getting the results I have posted. Will someone show me how I can access the change order information and produce the list?
if (componentType == CHANGE_ORDER_TYPE) {
if (!this.props.data) {
return null;
} else {
const changeList = this.props.data.map(function (result) {
return (result.change_orders);
});
// return resultsList;
console.log(changeList);
}
}
This is the current response from the map method above.
[
[
{
"id":1,
"change_order_name":"change 1",
"project_id":"1",
"cws_change_order_id":"33214324",
"slug":"change-1",
"created_at":null,
"updated_at":null
},
{
"id":2,
"change_order_name":"change 2",
"project_id":"1",
"cws_change_order_id":"3211324",
"slug":"change-2",
"created_at":null,
"updated_at":null
}
],
[
{
"id":3,
"change_order_name":"change 3",
"project_id":"2",
"cws_change_order_id":"3234324",
"slug":"change-3",
"created_at":null,
"updated_at":null
},
{
"id":4,
"change_order_name":"change 4",
"project_id":"2",
"cws_change_order_id":"6234532",
"slug":"change-4",
"created_at":null,
"updated_at":null
}
],
[
{
"id":5,
"change_order_name":"change 5",
"project_id":"3",
"cws_change_order_id":"3124214",
"slug":"change-5",
"created_at":null,
"updated_at":null
}
]
]
This is how I dug down to get get access to the individual change_orders
if (componentType == CHANGE_ORDER_TYPE) {
if (!this.props.data) {
return null;
} else {
const changeList = this.props.data.map(function (result) {
return (result.change_orders);
});
let changeOrdersArr = [];
for (let i = 0; i < changeList.length; i++) {
let inner = changeList[i];
for (let z = 0; z < inner.length; z++) {
changeOrdersArr.push(inner[z])
}
}
It's not entirely clear what your desired output is, but I think you want a single array with all change_orders in it? If this is correct then you can use the reduce function after your current map function:
if (componentType == CHANGE_ORDER_TYPE) {
if (!this.props.data) {
return null;
} else {
const changeList = this.props.data.map(function (result) {
return (result.change_orders);
}).reduce((output, item) => [...output, ...item], []);
// return changeList;
console.log(changeList);
}
}
const mapOutput = [
[
{
"id":1,
"change_order_name":"change 1",
"project_id":"1",
"cws_change_order_id":"33214324",
"slug":"change-1",
"created_at":null,
"updated_at":null
},
{
"id":2,
"change_order_name":"change 2",
"project_id":"1",
"cws_change_order_id":"3211324",
"slug":"change-2",
"created_at":null,
"updated_at":null
}
],
[
{
"id":3,
"change_order_name":"change 3",
"project_id":"2",
"cws_change_order_id":"3234324",
"slug":"change-3",
"created_at":null,
"updated_at":null
},
{
"id":4,
"change_order_name":"change 4",
"project_id":"2",
"cws_change_order_id":"6234532",
"slug":"change-4",
"created_at":null,
"updated_at":null
}
],
[
{
"id":5,
"change_order_name":"change 5",
"project_id":"3",
"cws_change_order_id":"3124214",
"slug":"change-5",
"created_at":null,
"updated_at":null
}
]
];
const change_orders = mapOutput.reduce((orders, arr) => [...orders,...arr],[]);
console.log(change_orders);

Categories