I have the following Javascript object:
var data = {
"customerSiteName": "Caldwell Sugar",
"AgreementID": "0",
"AgreementType": "",
"AgreementTypeID": {
"1": "Percentage Support",
"2": "Consignment Support",
"7": "Mobile Solutions",
"9": "SmartGlance Subscription",
"10": "Customer FIRST Lite",
"11": "Solution Support - LPS",
"12": "InSight Subscription"
},
"ProgramLevel": "",
"CFProgramLevelID": [
[1, "Primary"],
[2, "Standard"],
[3, "Premium"],
[4, "Elite"]
],
"DistributorID": "16",
"StartDate": "",
"EndDate": ""
};
I need to convert the key CFProgramLevelID which is an Array into a one dimension object. This is what I have tried so far:
$.each(data, function(key, value) {
if (value !== null && value instanceof Array) {
var obj = dataObj = value.reduce((p, c, i) => (Array.isArray(c) && (p[i] ={[c.length - 1]: c[c.length - 1]}), p), {});
console.log(obj);
}
});
But each value in CFProgramLevelID is converted to an object returning in this:
Object {0: Object, 1: Object, 2: Object, 3: Object}
0: Object
1: "Primary"
__proto__: Object
1: Object
1: "Standard"
__proto__: Object
2: Object
1: "Premium"
__proto__: Object
3: Object
1: "Elite"
__proto__: Object
What I want to get is as follow:
"CFProgramLevelID": {
"1": "Primary",
"2": "Standard",
"3": "Premium",
"4": "Elite"
}
What I am doing wrong?
I forgot to mention I have created a jsFiddle here
Updated your code, please see below (be mindful that this each loop will affect any array values that you have for a JSON key pair value, not just for CFProgramLevelID):
var data = {
"customerSiteName": "Caldwell Sugar",
"AgreementID": "0",
"AgreementType": "",
"AgreementTypeID": {
"1": "Percentage Support",
"2": "Consignment Support",
"7": "Mobile Solutions",
"9": "SmartGlance Subscription",
"10": "Customer FIRST Lite",
"11": "Solution Support - LPS",
"12": "InSight Subscription"
},
"ProgramLevel": "",
"CFProgramLevelID": [
[1, "Primary"],
[2, "Standard"],
[3, "Premium"],
[4, "Elite"]
],
"DistributorID": "16",
"StartDate": "",
"EndDate": ""
};
$.each(data, function(key, value) {
if (value !== null && value instanceof Array) {
var obj = dataObj = value.reduce((p, c, i) => (Array.isArray(c) && (p[i + 1] = c[c.length - 1]), p), {});
data[key] = obj;
console.log(obj);
console.log(data);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Your may do as follows;
var data = {
"customerSiteName": "Caldwell Sugar",
"AgreementID": "0",
"AgreementType": "",
"AgreementTypeID": {
"1": "Percentage Support",
"2": "Consignment Support",
"7": "Mobile Solutions",
"9": "SmartGlance Subscription",
"10": "Customer FIRST Lite",
"11": "Solution Support - LPS",
"12": "InSight Subscription"
},
"ProgramLevel": "",
"CFProgramLevelID": [
[1, "Primary"],
[2, "Standard"],
[3, "Premium"],
[4, "Elite"]
],
"DistributorID": "16",
"StartDate": "",
"EndDate": ""
},
result = data.CFProgramLevelID.reduce((r,sa) => Object.assign(r,{[sa[0]]:sa[1]}), {});
console.log(result);
Please try the following code.
var objectConstructor = {}.constructor;
var data = {}
object = {
"billing_address": {
"billingAddress": "d",
"billingCity": "e",
"billingState": "f"
},
"shipping_address": {
"shippingAddress": "a",
"shippingCity": "b",
"shippingState": "c"
}
}
a(object);
function a(obj, key) {
if (!obj) {
return;
} else if (obj.constructor !== objectConstructor) {
data[key] = obj;
} else {
Object.keys(obj).map((key, index) => {
a(obj[key], key);
})
}
}
console.log(data)
I hope it helps.
Thanks.
Related
I'm trying to organise data from an api that returns the following json:
[
{
"0": "THURSDAY 25th MARCH",
"1": "",
"2": ""
},
{
"0": "Snow Patrol",
"1": "Press Conference",
"2": "16:00 - 19:35"
},
{
"0": "",
"1": "",
"2": ""
},
{
"0": "FRIDAY 26th MARCH",
"1": "",
"2": ""
},
{
"0": "Arctic Moneys",
"1": "Concert",
"2": "11:55 - 12:40"
},
{
"0": "Rush",
"1": "Practice Session",
"2": "13:05 - 13:50"
}
]
The api returns an array with only numbers as keys and the next date starts after and empty object.
Into an organised array like so:
[
{
"date": "THURSDAY 25th MARCH",
"events": [
{
"band": "Snow Patrol",
"type": "Press Conference",
"time": "16:00 - 19:35"
}
]
},
{
"date": "FRIDAY 26th MARCH",
"events": [
{
"band": "Arctic Moneys",
"type": "Concert",
"time": "11:55 - 12:40"
},
{
"band": "Rush",
"type": "Practice Session",
"time": "13:05 - 13:50"
}
]
}
]
Any help would be much appreciated!
Cheers!
You could create an array of each object and check if all vlaues are empty strings or the last two ones.
The continue or build a new date object and add later all events to the last object.
const
data = [{ 0: "THURSDAY 25th MARCH", 1: "", 2: "" }, { 0: "Snow Patrol", 1: "Press Conference", 2: "16:00 - 19:35" }, { 0: "", 1: "", 2: "" }, { 0: "FRIDAY 26th MARCH", 1: "", 2: "" }, { 0: "Arctic Moneys", 1: "Concert", 2: "11:55 - 12:40" }, { 0: "Rush", 1: "Practice Session", 2: "13:05 - 13:50" }],
result = data.reduce((r, o) => {
const a = Object.assign([], o);
if (!a.join('')) return r;
if (!a.slice(1).join('')) {
r.push({ date: a[0], events: [] });
} else {
const [band, type, time] = a;
r[r.length - 1].events.push({ band, type, time });
}
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have an array of object that looks like this:
[
{ "customer": "2222", "owners": { "1": "aaa", "2": "bbb" }, "title": "V1" },
{ "customer": "1111", "owners": { "1": "aaa", "2": "bbb" }, "title": "V2" }
]
I want to filter the array to contain only the owners field.
[
{"owners": { "1": "aaa", "2": "bbb" }},
{"owners": { "1": "aaa", "2": "bbb" }}
]
I tried something like
const filterArr = (arr, obj) => taskArray.filter( task => Object.keys(task).some( key => obj[key]));
But it doesn't work because it is not really referring to the name of the key in the array.
Any help?
You don't need filter, you can just use Array.prototype.map to map each object in the original array to another object having the structure you want:
var arr = [
{ "customer": "2222", "owners": { "1": "aaa", "2": "bbb" }, "title": "V1" },
{ "customer": "1111", "owners": { "1": "aaa", "2": "bbb" }, "title": "V2" }
]
var result = arr.map(obj => ({'owners' : obj['owners']}));
console.log(result);
Using Map function, you will get undefined if owners don't exist.
var arr = [
{ "customer": "2222", "owners": { "1": "aaa", "2": "bbb" }, "title": "V1" },
{ "customer": "1111", "owners": { "1": "aaa", "2": "bbb" }, "title": "V2" }
];
function pluckArray(array,key){
var a = [],
i={},i1 = -1, i2 = array.length,
o ;
while(++i1 < i2)
{
o = array[i1] ; // you have to use the bracket operator here
if(o.hasOwnProperty(key)){
i[key] = o[key];
a.push(i);
} ;
}
return a;
}
console.log(pluckArray(arr, 'title' ));
My object array looks like this:
[
{
"id": "0",
"title": "Exercise",
"main_object": {
"title": "Exercise",
"number1": {
"1": "10",
"2": "10",
"3": "5",
"4": "20",
},
"sumtype": {
"1": "+",
"2": "-",
"3": "x",
"4": ":",
},
"number2": {
"1": "10",
"2": "5",
"3": "2",
"4": "2",
}
}
}
]
Now how would I use this to create an array in javascript (and jquery if it has an easier way of doing this) that has the answers to these simple sums. So the first string in the array would be 10 + 10 which would give 20. The second string should be 10 - 5 giving 5.
I use $.getJSON to retrieve my JSON and I tried a simple for loop like this:
var sumanswers = [];
var keyamount = Object.keys(exerSumType);
var keylength = keyamount.length;
for (i = 0; i < keylength; i++) {
sumanswers[i] = exerNumber1[i] + exerSumType[i] + exerNumber2[i];
}
This just gives me the sum as a string (e.g. "10+10") while I want "20". Other then that for some reason this doesn't give me all the sums, it gives me this when I console.log(sumanswers):
0: NaN
1: "10+10"
2: "10-5"
3: "5x2"
So I'm missing my last sum and getting NaN as a first sum for some reason.
Any help would be greatly appreciated!
var exercises = [{
"id": "0",
"title": "Exercise",
"main_object": {
"title": "Exercise",
"number1": {
"1": "10",
"2": "10",
"3": "5",
"4": "20",
},
"sumtype": {
"1": "+",
"2": "-",
"3": "x",
"4": ":",
},
"number2": {
"1": "10",
"2": "5",
"3": "2",
"4": "2",
}
}
}]
var sumanswers = [];
var keyamount = Object.keys(exerSumType);
var keylength = keyamount.length;
for (i = 0; i < keylength; i++) {
sumanswers[i] = exerNumber1[i] + exerSumType[i] + exerNumber2[i];
console.log(sumanswers[i] , exerNumber1[i] , exerSumType[i] , exerNumber2[i])
}
You could use an array for enumerable data. Arrays are zero based, so the index starts from zero.
For calculating some value with a given operand, you could take an object with all operands as keys.
var data = [{ id: "0", title: "Exercise", main_object: { title: "Exercise", number1: { "1": "10", "2": "10", "3": "5", "4": "20" }, sumtype: { "1": "+", "2": "-", "3": "x", "4": ":" }, number2: { "1": "10", "2": "5", "3": "2", "4": "2" } } }],
op = {
'+': (a, b) => +a + +b,
'-': (a, b) => a - b,
'x': (a, b) => a * b,
':': (a, b) => a / b
};
data.forEach(({ main_object }) => {
main_object.answers = {};
var { answers, number1, number2, sumtype } = main_object;
Object
.keys(main_object.number1)
.forEach(k => answers[k] = op[sumtype[k]](number1[k], number2[k]))
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here is a working snippet suing ES6; Object.keys, Array.reduce, Spread operator, Dynamic key name.
const obj = {
number1: {
1: '10',
2: '10',
3: '5',
4: '20',
},
sumtype: {
1: '+',
2: '-',
3: 'x',
4: ':',
},
number2: {
1: '10',
2: '5',
3: '2',
4: '2',
},
};
function makeOp(n1, op, n2) {
return ({
'+': () => n1 + n2,
'-': () => n1 - n2,
'x': () => n1 * n2,
':': () => n1 / n2,
}[op])();
}
const res = Object.keys(obj.number1).reduce((tmp, x) => ({
...tmp,
[x]: makeOp(Number(obj.number1[x]), obj.sumtype[x], Number(obj.number2[x])),
}), {});
console.log(res);
var test = [
{
"id": "0",
"title": "Exercise",
"main_object": {
"title": "Exercise",
"number1": {
"1": "10",
"2": "10",
"3": "5",
"4": "20",
},
"sumtype": {
"1": "+",
"2": "-",
"3": "x",
"4": ":",
},
"number2": {
"1": "10",
"2": "5",
"3": "2",
"4": "2",
}
}
}
]
var test = [
{
"id": "0",
"title": "Exercise",
"main_object": {
"title": "Exercise",
"number1": {
"1": "10",
"2": "10",
"3": "5",
"4": "20",
},
"sumtype": {
"1": "+",
"2": "-",
"3": "x",
"4": ":",
},
"number2": {
"1": "10",
"2": "5",
"3": "2",
"4": "2",
}
}
}
]
test.forEach(ele=> {
for (let index in ele.main_object.number1){
var text = ele.main_object;
var num1 = text.number1[index];
var op = text.sumtype[index];
op = op === 'x' ? "*" : op
op = op === ':' ? "/" : op
var num2 = text.number2[index];
console.log(num1 + text.sumtype[index] + num2 +'=' + eval(num1 + op + num2))
}
})
Eval for the win!
Use eval(string) to execute the string as if it were plain old JavaScript
sumanswers.map(sumanswer => eval(sumanswer))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
I have this object value
var data = {
"questions": {
"0": {
"0": "17",
"1": "12"
},
"1": {
"0": "22",
"1": "34"
},
"2": {
"0": "52",
"1": "61"
}
}
}
I am trying to get value from these objects as I have tried below things which return me other than what I actually want.
alert(Object.keys(data.questions[0])); // Output : 0,1
alert(Object.keys(data.questions[0][0])); // Output : 0
alert(Object.keys(data.questions[0][1])); // Output : 0
Anyone can help me find the value of above keys like:
questions[0][0] = 17
questions[0][1] = 12
Try like this.
var data = {
"questions": {
"0": {
"0": "17",
"1": "12"
},
"1": {
"0": "22",
"1": "34"
},
"2": {
"0": "52",
"1": "61"
}
}
}
console.log(data.questions["0"]);
console.log(data.questions["0"]["0"]);
console.log(data.questions["0"]["1"]);
To get length of any particular question (in your data structure) use
Object.keys(data.questions["0"]) or Object.keys(data.questions["1"])
to get value of any questions use
data.questions["0"]["0"] or data.questions["0"]["1"] or data.questions["1"]["0"] and so on..
You get the result without Object.keys.
var data = { questions: { 0: { 0: "17", 1: "12" }, 1: { 0: "22", 1: "34" }, 2: { 0: "52", 1: "61" } } };
console.log(data.questions[0]); // { 0: "17", 1: "12" }
console.log(data.questions[0][0]); // 17
console.log(data.questions[0][1]); // 12
For searching a value's path of keys, you could use an iterative and recursive approach by checking all keys and objects.
function findValue(object, value) {
var p;
Object.keys(object).some(function (k) {
var t;
if (object[k] === value) {
p = [k];
return true;
}
if (object[k] && typeof object[k] === 'object' && (t = findValue(object[k], value))) {
p = [k].concat(t);
return true;
}
});
return p;
}
var data = { questions: { 0: { 0: "17", 1: "12" }, 1: { 0: "22", 1: "34" }, 2: { 0: "52", 1: "61" } } };
console.log(findValue(data, '17'));
console.log(findValue(data, '34'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Can you change the data structure? If I were you I would change it to the following:
var data = {
"questions": [
[17, 22],
[22, 34],
[52, 61]
]
};
console.log(data.questions[0]); // Output : 17,22
console.log(data.questions[0][0]); // Output : 17
console.log(data.questions[1][1]); // Output : 34
To access the first object ["0"]
To access the first two object : ["0"]["0"] and so on
based on the above expression we can access the objects like this
var data = {
"questions": {
"0": {
"0": "17",
"1": "12"
},
"1": {
"0": "22",
"1": "34"
},
"2": {
"0": "52",
"1": "61"
}
}
}
console.log(data.questions["0"]);
console.log(data.questions["0"]["0"]);
console.log(data.questions["0"]["1"]);
console.log(data.questions["1"]["1"]);
I'm having a hard time wrapping my head around key value (which are arrays) into a node based/treemap structure. Below is some sample code to help explain.
I'd like to convert this...
// key value data
var rawData = {
"1": [],
"2": [10],
"3": [2,5,11],
"4": [],
"5": [1,7,6],
"6": [4],
"7": [],
"8": [9],
"9": [],
"10": [],
"11": []
}
to this tree map...
// tree map
var treeData = {
"id": "ALL",
"contents": [
{
"id": "3",
"contents": [
{
"id": "2",
"contents": [
{ "id": "10" }
]
}, {
"id": "5",
"contents": [
{ "id": "1" },
{ "id": "7" },
{
"id": "6",
"contents": [
{ "id": "4" }
]
}
]
},
{ "id": "11" }
]
},
{
"id": "8",
"contents": [
{ "id": "9" }
]
}
]
}
I believe some form of recursion is involved but I'm having a tough time traversing through the nodes...
var traverse = function(rawData) {
for (var i in rawData){
var datum = rawData[i];
for (var j in datum) {
if(i===datum[j]){
// tack on node to datum
}
traverse(rawData);
}
}
}
Iterating through array in not possible with for in, instead:
for (var j = 0; j < datum.length; i++) {
if(i===datum[j]){
// tack on node to datum
}
traverse(rawData);
}