I'm looking to create a valid nested Json file, from an array, with unique keys value. Currently, I'm only able to to display the json without any nested structure.
I would like to display to the console the following structure :
{
"Key" : "data1",
"header" : {
"title" : "data2",
"tag1" : "data3",
"tag2" : "data4"
},
"body" : {
"text" : "data5"
},
"updates" : {
"title" : "data6",
"text" : "data7"
},
"footer" : {
"title" : "data8",
"row1" :{
"col1" : {
"title" : "data9",
"text" : "data10"
},
"col2" : {
"title" : "data11",
"text" : "data12"
},
"col3" : {
"title" : "data13",
"text" : "data14"
}
},
"row2" :{
"col1" : {
"title" : "data15",
"text" : "data16"
},
"col2" : {
"title" : "data17",
"text" : "data18"
},
"col3" : {
"title" : "data19",
"text" : "data20"
}
},
"row3" :{
"col1" : {
"title" : "data22",
"text" : "data23"
},
"col2" : {
"title" : "data24",
"titlebis" : "data25",
"text" : "data26"
},
"col3" : {
"title" : "data27",
"text" : "data28"
}
},
"row4" :{
"col1" : {
"title" : "data29"
},
"website" : "data30",
"website-link" : "data31",
"email" : "data38",
"privacy" : "data32",
"privacy-link" : "data33",
"adr" : "data34",
"adr2" : "data35"
}
},
"other" : {
"short" : {
"des" : "data36"
},
"promovideo" : "data37"
}
}
here is what I already done:
var data = [["Key", "data1"],
["header.title", "data2"],
["header.tag1", "data3"],
["header.tag2", "data4"],
["body.text", "data5"],
["updates.title", "data6"],
["updates.text", "data7"],
["footer.title", "data8"],
["footer.row1.col1.title", "data9"],
["footer.row1.col1.text", "data10"],
["footer.row1.col2.title", "data11"],
["footer.row1.col2.text", "data12"],
["footer.row1.col3.title", "data13"],
["footer.row1.col3.text", "data14"],
["footer.row2.col1.title", "data15"],
["footer.row2.col1.text", "data16"],
["footer.row2.col2.title", "data17"],
["footer.row2.col2.text2", "data18"],
["footer.row2.col3.title", "data19"],
["footer.row2.col3.text", "data20"],
["footer.row3.col1.title", "data22"],
["footer.row3.col1.text", "data23"],
["footer.row3.col2.title", "data24"],
["footer.row3.col2.title", "data25"],
["footer.row3.col2.text", "data26"],
["footer.row3.col3.title", "data27"],
["footer.row3.col3.text", "data28"],
["footer.row4.col1.title", "data29"],
["footer.row4.website", "data30"],
["footer.row4.website-link", "data31"],
["footer.row4.email", "data31"],
["footer.row4.privacy", "data32"],
["footer.row4.privacy-link", "data33"],
["footer.row4.adr", "data34"],
["footer.row4.adr2", "data35"],
["other.short.des", "data36"],
["other.promovideo", "data37"],
];
// console.log(data);
data.sort(alphabetical); // Sort alphabetically our 2D array
CreateAndDisplayJson(data);
// Create a JSON file from Keys Trad Data
function CreateAndDisplayJson(GetKeysTraductionArrayData) {
var lenght = GetKeysTraductionArrayData.length;
var output = "{\n";
for (var i = 0; i < GetKeysTraductionArrayData.length; i++) {
var key = GetKeysTraductionArrayData[i][0];
var trad = GetKeysTraductionArrayData[i][1];
var nameSplit = key.split("."); // Check how many times we need to indent json from Key
if(nameSplit.length>1) { // The Key needs to be indented
var closeBraket = "";
var spacing = ""; // Json indentation
var saveSpacingTab = []; // Closing indentation
for (j=0; j <nameSplit.length; j++){ // We add the key + indentation
output += spacing+"\""+nameSplit[j]+"\" : { \n";
if (j==0 && i != GetKeysTraductionArrayData.length-1) {
closeBraket = spacing+"}, \n";
} else {
closeBraket = spacing+"} \n";
}
spacing +=" ";
saveSpacingTab[j] = closeBraket;
closingText = "";
if (j==nameSplit.length-1) { // last indentation of the Key
saveSpacingTab.reverse();
for ( k=0; k < saveSpacingTab.length ; k++) { // We create the Bracket indentation
closingText += saveSpacingTab[k];
}
output += spacing+"\""+nameSplit[j]+"\" : " + "\""+trad +"\"\n" + closingText; // last Row
}
}
} else {
output += "\""+key+"\" : " + "\""+trad +"\", \n";
}
}
// output += "}" + outputCommented;
output += "}";
console.log(output);
return output;
}
// Sort alphabetically our 2D array
function alphabetical(a, b) {
var A = a[0];
var B = b[0].toLowerCase();
A = A.toLowerCase();
B = B.toLowerCase();
if (A < B) return -1;
if (A > B) return 1;
return 0;
}
You can use forEach loop and inside split each key and then use reduce to build nested structure for each key.
var data = [["Key","data1"],["header.title","data2"],["header.tag1","data3"],["header.tag2","data4"],["body.text","data5"],["updates.title","data6"],["updates.text","data7"],["footer.title","data8"],["footer.row1.col1.title","data9"],["footer.row1.col1.text","data10"],["footer.row1.col2.title","data11"],["footer.row1.col2.text","data12"],["footer.row1.col3.title","data13"],["footer.row1.col3.text","data14"],["footer.row2.col1.title","data15"],["footer.row2.col1.text","data16"],["footer.row2.col2.title","data17"],["footer.row2.col2.text2","data18"],["footer.row2.col3.title","data19"],["footer.row2.col3.text","data20"],["footer.row3.col1.title","data22"],["footer.row3.col1.text","data23"],["footer.row3.col2.title","data24"],["footer.row3.col2.title","data25"],["footer.row3.col2.text","data26"],["footer.row3.col3.title","data27"],["footer.row3.col3.text","data28"],["footer.row4.col1.title","data29"],["footer.row4.website","data30"],["footer.row4.website-link","data31"],["footer.row4.email","data31"],["footer.row4.privacy","data32"],["footer.row4.privacy-link","data33"],["footer.row4.adr","data34"],["footer.row4.adr2","data35"],["other.short.des","data36"],["other.promovideo","data37"]]
let result = {}
data.forEach(([key, value]) => {
key.split('.').reduce((r, k, i, arr) => {
return r[k] || (r[k] = arr[i + 1] ? {} : value)
}, result)
})
console.log(result)
A non-ternary solution with reduce:
const data = [["Key","data1"],["header.title","data2"],["header.tag1","data3"],["header.tag2","data4"],["body.text","data5"],["updates.title","data6"],["updates.text","data7"],["footer.title","data8"],["footer.row1.col1.title","data9"],["footer.row1.col1.text","data10"],["footer.row1.col2.title","data11"],["footer.row1.col2.text","data12"],["footer.row1.col3.title","data13"],["footer.row1.col3.text","data14"],["footer.row2.col1.title","data15"],["footer.row2.col1.text","data16"],["footer.row2.col2.title","data17"],["footer.row2.col2.text2","data18"],["footer.row2.col3.title","data19"],["footer.row2.col3.text","data20"],["footer.row3.col1.title","data22"],["footer.row3.col1.text","data23"],["footer.row3.col2.title","data24"],["footer.row3.col2.title","data25"],["footer.row3.col2.text","data26"],["footer.row3.col3.title","data27"],["footer.row3.col3.text","data28"],["footer.row4.col1.title","data29"],["footer.row4.website","data30"],["footer.row4.website-link","data31"],["footer.row4.email","data31"],["footer.row4.privacy","data32"],["footer.row4.privacy-link","data33"],["footer.row4.adr","data34"],["footer.row4.adr2","data35"],["other.short.des","data36"],["other.promovideo","data37"]]
const result = data.reduce((all, [keys, val]) => {
keys.split('.').reduce((obj, key, i, arr) => {
if (i === arr.length - 1) {
obj[key] = val;
} else {
if (!obj.hasOwnProperty(key)) {
obj[key] = {};
};
}
return obj[key];
}, all);
return all;
}, {});
console.log(result);
Related
"course_DxhYTv2copzWyBhKo" : {
"interest" : "DxhYTv2copzWyBhKo",
"type" : "course",
"affinity" : 3
}
From Object Name "course_DxhYTv2copzWyBhKo",
I want to slice "DxhYTv2copzWyBhKo"
Using String#split:
const data = {
"course_DxhYTv2copzWyBhKo" : {
"interest" : "DxhYTv2copzWyBhKo",
"type" : "course",
"affinity" : 3
}
};
const key = Object.keys(data)[0];
const sliceAfterSubStr = "course_";
const slicedSubStr = key.split(sliceAfterSubStr)[1];
console.log(slicedSubStr);
Using String#substr:
const data = {
"course_DxhYTv2copzWyBhKo" : {
"interest" : "DxhYTv2copzWyBhKo",
"type" : "course",
"affinity" : 3
}
};
const key = Object.keys(data)[0];
const sliceAfterSubStr = "course_";
const sliceIndex = key.indexOf(sliceAfterSubStr);
const slicedSubStr = sliceIndex !== -1
? key.substr( sliceIndex + sliceAfterSubStr.length )
: undefined;
console.log(slicedSubStr);
You can use the split operation on a string. Take a look at the following code snippet.
const courses = {
"course_DxhYTv2copzWyBhKo": {
"interest": "DxhYTv2copzWyBhKo",
"type": "course",
"affinity": 3
},
"course_DSdasdnDASnoiddDs": {
"interest": "DSdasdnDASnoiddDs",
"type": "course",
"affinity": 3
}
}
console.log(Object.keys(courses).map(key => key.split("_")[1]))
im struggling a little with this, been a while since ive coded javascript ... trying to convert this
items = {
"data": [
{
"name" : "john"
},
{
"name" : "james"
},
{
"name" : "joe"
},
{
"name" : "brian"
},
{
"name" : "bojan"
},
{
"name" : "billy"
},
{
"name" : "dean"
},
{
"name" : "darren"
},
{
"name" : "doug"
}
]
}
into this format
items = {
"data": [
{
letter: "j"
names : ["john", "james", "joe"]
},
{
letter: "b"
names : ["brian", "bojan", "billy"]
},
{
letter: "j"
names : ["dean", "darren", "doug"]
},
]
}
I've been trying to do this using reduce but not having much look.... is there a simpler way to to do it?
You can use reduce to create an object with the letters as keys from which you can extrapolate the array of objects you need by iterating over the object entries using map.
const items = {"data":[{"name":"john"},{"name":"james"},{"name":"joe"},{"name":"brian"},{"name":"bojan"},{"name":"billy"},{"name":"dean"},{"name":"darren"},{"name":"doug"}]};
// `reduce` over the data to produce an object
// with letter keys, and array values where the names are added
const obj = items.data.reduce((acc, c) => {
const letter = c.name[0];
acc[letter] = (acc[letter] || []).concat(c.name);
return acc;
}, {})
// `map` over the object entries to return an array of objects
items.data = Object.entries(obj).map(([letter, names]) => {
return { letter, names }
}).sort((a, b) => a.letter > b.letter);
console.log(items);
Vanilla javascript implementation:
const items = {
"data": [
{
"name" : "john"
},
{
"name" : "james"
},
{
"name" : "joe"
},
{
"name" : "brian"
},
{
"name" : "bojan"
},
{
"name" : "billy"
},
{
"name" : "dean"
},
{
"name" : "darren"
},
{
"name" : "doug"
}
]
}
const transformed = {
data:[]
}
const findByLetter = (letter) => (element) => element.letter === letter;
for(let i = 0; i < items.data.length; i++){
const letter = items.data[i].name.split("")[0];
const elIndex = transformed.data.findIndex(findByLetter(letter));
if(elIndex > -1){
transformed.data[elIndex].names.push(items.data[i].name);
}else{
transformed.data.push({
letter,
names: [items.data[i].name],
});
}
};
console.log(transformed);
Use one reduce():
const items = {"data":[{"name":"john"},{"name":"james"},{"name":"joe"},{"name":"brian"},{"name":"bojan"},{"name":"billy"},{"name":"dean"},{"name":"darren"},{"name":"doug"}]};
let res = items.data.reduce((acc, item) => {
let l = item.name[0];
if (acc.data.filter(e => e.letter == l)[0] === undefined) acc.data.push({'letter': l, names: [] });
acc.data.filter(e => e.letter == l)[0].names.push(item.name);
return acc;
}, {"data": []})
console.log(res)
Original JSON
var dataJson = [{
"MID" : "NTE",
"TNAME" : "gGAR",
"MVALUE" : 6
}, {
"MID" : "NTP",
"TNAME" : "gGAR",
"MVALUE" : 50
}, {
"MID" : "NTR",
"TNAME" : "gGAR",
"MVALUE" : 12
}, {
"MID" : "NTE",
"TNAME" : "gRRR",
"MVALUE" : 1
}, {
"MID" : "NTP",
"TNAME" : "gRRR",
"MVALUE" : 100
}, {
"MID" : "NTR",
"TNAME" : "gRRR",
"MVALUE" : 1
}];
Need to group by "TNAME" and after all the group taking first three objects based on "MID" and modify the JSON structure like
Expected output JSON:
var Convert = [
{
"GGARMVALUENTE":6,
"GGARMVALUENTP":50,
"GGARMVALUENTR":12,
"GRRRMVALUENTE":1,
"GRRRMVALUENTP":100,
"GRRRMVALUENTR":1
}
]
Finally it works according to your requirements. Just Solved Puzzling Question. :)
function restructure (data) {
let convert = []
let buffer = null
let pairs = data.map(d => {
return [`${d.TNAME.toUpperCase()}MVALUE${d.MID}`, d.MVALUE]
})
pairs.forEach((p, i) => {
let name = p.shift()
let value = p.shift()
let pair = {
[name]: value
}
if (buffer && buffer[name]) {
convert.push(buffer)
delete buffer
buffer = pair
} else {
if (buffer) {
Object.assign(buffer, pair)
} else {
buffer = pair
}
if (pairs.length === i + 1) {
convert.push(buffer)
delete buffer
}
}
})
return convert
}
console.log(restructure(dataJson))
I have an array of objects similar to this :
var this array = [
{
"id" : "A20",
"age" : "16"
},
{
"id" : "A2",
"age" : "12"
},
{
"id" : "B16",
"age" : "45"
}]
I need to sort this array by their ID, So it would end up like :
this array = [
{
"id" : "A2",
"age" : "12"
},
{
"id" : "A20",
"age" : "16"
},
{
"id" : "B16",
"age" : "45"
}]
I have this method of sorting :
nodes.sort(function(a,b){
// console.log(a.Pos)
// console.log(a.pinNum)
var alc = a.id, blc = b.id;
console.log(alc)
return alc > blc ? 1 : alc < blc ? -1 : 0;
});
But this only works alphabetically. I have also found this but it gives back just the strings I pass to the function not the array of objects :
function sortArray(arr) {
var tempArr = [],
n;
console.log(arr)
for (var i in arr) {
var thisString = arr[i].id;
// tempArr[i] = arr[i].match(/([^0-9]+)|([0-9]+)/g);
tempArr[i] = thisString.match(/([^0-9]+)|([0-9]+)/g);
for (var j in tempArr[i]) {
if (!isNaN(n = parseInt(tempArr[i][j]))) {
tempArr[i][j] = n;
}
}
}
tempArr.sort(function (x, y) {
for (var i in x) {
if (y.length < i || x[i] < y[i]) {
return -1; // x is longer
}
if (x[i] > y[i]) {
return 1;
}
}
return 0;
});
for (var i in tempArr) {
arr[i] = tempArr[i].join('');
}
return arr;
}
console.log(sortArray(nodes).join(","));
What I need is the second sorting function but with the ability to sort both alphabetically and numerically. Thanks
var array = [{
"id" : "A20",
"age" : "16"
}, {
"id" : "A2",
"age" : "12"
}, {
"id" : "B16",
"age" : "45"
}];
array.sort(function(a, b) {
var aSplit = /(\D*)(\d*)/.exec(a.id),
bSplit = /(\D*)(\d*)/.exec(b.id);
if( aSplit[1] !== bSplit[1] )
return aSplit[1].localeCompare(bSplit[1]);
else
return aSplit[2] - bSplit[2];
});
Use function .sort in array, and pass has argument, a callback.
This callback receive elements to iterate, and you can compare values, if return true, switch order of elements, for i.e:
arr.sort(function(a, b) {
return parseInt(a.age) > parseInt(b.age))
};
or, if you use ecma script 6, you can use arrow function, is better, i.e. below:
arr.sort((a, b) => parseInt(a.age) > parseInt(b.age))
Docs here:
http://www.w3schools.com/jsref/jsref_sort.asp
I think you can use localeCompare() to compare strings. Try this code, it should work:
nodes.sort(function(a,b){
// console.log(a.Pos)
// console.log(a.pinNum)
var alc = a.id, blc = b.id;
console.log(alc)
return alc.localeCompare(blc);
});
Input:
{ key : "value" ,
list : [
{
key : "values1" ,
list : [
{ key : "value2" , list :[{ key : "simpleValue" } ]
}
]
},
{
key : "value3"
}
]
}
Output:
{key : ["value" , "values1" , "values2" , "simpleeValue", "values3"]}
the code that I wrote for conversion is
var outputArray=new Array();
var count=0;
function recursion(testData){
if(testData.key==undefined)
{
return ;
}
else
{
outputArray[count]=testData.key;
count++;
for(var k in testData.list)
{
testData1=testData.list[k];
recursion(testData1);
recursion(testData.key);
}
}
return outputArray;
}
The output will only give me the value list an array,like [
'value',
'values1',
'value2',
'simpleValue',
'value3'
], how do I use the hash method to get the correct output?
Hmm, something like this??
var inpObj = { key : "value" ,list : [
{
key : "values1"
},
{
key : "value3"
}
]
};
var outputObj = new Object;
var outputArray = new Array();
function recursion(testData){
if(testData.key==undefined)
{
return;
}
else
{
var newKey={};
//alert(testData.key);
outputArray.push(testData.key);
for(var k in testData.list)
{
testData1=testData.list[k];
recursion(testData1);
recursion(testData.key);
}
}
return outputArray;
}
recursion(inpObj);
if (outputObj.key == undefined) outputObj.key = outputArray;
alert(outputObj.key.join(", "));
I got this thing sorted out
var outputArray=new Array();
function recursion(testData){
if(testData.key==undefined)
{
return ;
}
else
{
//alert(testData.key);
outputArray.push(testData.key);
for(var k in testData.list)
{
testData1=testData.list[k];
recursion(testData1);
recursion(testData.key);
}
}
var l={};
l.key=outputArray;
return l;
}