Change JSON string structure - javascript

I have a JSON string which looks like this:
[
{
"queryResult": {
"A": "12-04-2014",
"B": 1
}
},
{
"queryResult": {
"A": "13-04-2014",
"B": 2
}
},
{
"queryResult": {
"A": "14-04-2014",
"B": 3
}
}
]
And I need to parse it and change it to this
[
{
"A": "12-04-2014",
"B": 1
},
{
"A": "13-04-2014",
"B": 2
},
{
"A": "14-04-2014",
"B": 3
}
]
I already have a function for making that change, which is:
function justAnExample() {
var jsonData = exampleJSON(); //Obtains the JSON
var finalJSON=JSON.stringify(jsonData[0]['queryResult']);
for (var i = 1; i < jsonData.length; i++) {
finalJSON = finalJSON+','+JSON.stringify(jsonData[i]['queryResult']);
}
return JSON.parse('[' + finalJSON + ']');
}
But, this method uses stringifying and then parsing JSON to recreate the JSON object, which works, but is there a better solution, in which I can work with the object notation itself.
P.S: I know the term "JSON object" is a semi-pseudo thing, and that only the JSON notation/format matters, but, just need to confirm if this is the proper way to do it.
Edit
Please find a JS fiddle for the problem
http://jsfiddle.net/mukilr/uJV54/

You can do:
var json = [
{
"queryResult": {
"A": "12-04-2014",
"B": 1
}
},
{
"queryResult": {
"A": "13-04-2014",
"B": 2
}
},
{
"queryResult": {
"A": "14-04-2014",
"B": 3
}
}
];
var out = [];
for (var i = 0; i < json.length; i++){
out[i] = json[i].queryResult;
}
check this fiddle
EDIT
This is your fiddle updated

Related

I'm getting wrong output in Javascript Function?

I have function that looks through an array of objects (first argument) and returns an array of all objects that have matching name and value pairs (second argument). Each name and value pair of the source object has to be present in the object from the collection if it is to be included in the returned array.
function whatIsInAName(collection, source) {
let keyArr = Object.keys(source);
for (let i = 0; i < keyArr.length; i++) {
var arr = collection.filter(function(item) {
return item.hasOwnProperty(keyArr[i])
})
}
return arr.filter(function(item) {
for (let g = 0; g < keyArr.length; g++) {
return item[keyArr[g]] === source[keyArr[g]];
}
});
}
console.log(whatIsInAName([{
"a": 1,
"b": 2,
"c": 3
}], {
"a": 1,
"b": 9999,
"c": 3
}));
I should give an empty array [ ].
but It is giving [{"a": 1, "b": 2, "c": 3}]
You had an error in your second filter.
In for statement you were returning comparision result of first item from that statement and not checking if whole arr is equal.
In code below I have changed for statement to return false when items doesn't match. Then at the end there is returned true becouse there wasn't found any item that doesn't match with the other arr.
function whatIsInAName(collection, source) {
let keyArr = Object.keys(source);
for(let i = 0; i < keyArr.length; i++){
var arr = collection.filter(item => item.hasOwnProperty(keyArr[i]));
}
return arr.filter(item => {
for(let g = 0; g < keyArr.length; g++) {
if (item[keyArr[g]] !== source[keyArr[g]]) {
return false;
}
}
return true;
});
}
console.log(
whatIsInAName(
[{"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 9999, "c": 3}],
{"a": 1, "b": 9999, "c": 3}
)
);
What is the first loop for? The arr created there is overwritten in every iteration of the loop. So the final arr will be the array of items which at least contain the last property in Object.keys(). You can apply your filter directly on the collections parameter.
function whatIsInAName(collection, source) {
let keys = Object.keys(source);
return collection.filter(item => keys.every(k => item[k] === source[k]));
}
console.log(whatIsInAName([
{"a": 1, "b": 9999, "c": 3 },
{"a": 2, "b": 9999, "c": 3 },
{"a": 1, "b": 2, "c": 3 },
{"a": 1, "b": 9999, "c": 3, "d": 4 }
],
{"a": 1, "b": 9999, "c": 3}));
Keep in mind that the equality check === will only work for primitive values but not for objects or arrays. Also this approach will accept additional properties in the items of the collection, that are not present in the source item.

Object destructing using ES6

I have this nested object that contains also an array.
result:{
"a": [{ "b": { "c": 1,
"d": 2,
"e": 3
},
"f": 0
}]
}
How can I destructure this object using ES6 if I need the value of d?
Object destructuring notation is just like object literal notation, just on the other side of the equals sign. So you write exactly what you'd write to only create the structure necessary for d, and put your d variable/constant name there.
It looks like you're showing us the contents of your object (e.g., it has a property called result), so:
const obj = {
result: {
"a": [{
"b": {
"c": 1,
"d": 2,
"e": 3
},
"f": 0
}]
}
};
const {
result: {
"a": [{
"b": {
d
}
}]
}
} = obj;
console.log(d);
I'm not saying I'd use destructuring here. In fact, I probably wouldn't. But you can. :-)
If result was the variable containing the object, just remove that layer:
const obj = {
"a": [{
"b": {
"c": 1,
"d": 2,
"e": 3
},
"f": 0
}]
};
const {
"a": [{
"b": {
d
}
}]
} = obj;
console.log(d);
Of course, that's taking your question at face value that you want the d from the first entry in a. You can generalize it to get entry n like this (I'm back to assuming result is part of the object):
const obj = {
result: {
"a": [
{
"b": {
"c": 1,
"d": 2,
"e": 3
},
"f": 0
},
{
"b": {
"c": 1,
"d": 4, // ***
"e": 3
},
"f": 0
}
]
}
};
const n = 1; // Which entry in `a` to get
const {
result: {
"a": {
[n]: {
"b": {
d
}
}
}
}
} = obj;
console.log(d);
I'm using object destructuring for a rather than array destructuring, with a computed property name. I can do that because arrays are objects.
Array destructuring notation is just like array literal notation, too. :-)
You want the value of d?
result.a[0].b.d ?

Retrieving JSON object value from Javascript

I am new to Javascript and JSON. I want to get the following JSON values via Javascript. I need to retrieve the "login" value and add up the "a", "d" and "c" respectively. I managed to get "login" value but I couldn't figure out how do i retrieve "a", "d" and "c" values.
var data = JSON.parse(text);
$.each(data, function(i, v) {
var login = v.login; // Get "login"
var commits = 0;
var additions = 0;
var deletions = 0;
var contributions = 0;
$.each(data, function(j, w) {
commits += w.c; // Get "c"
additions += w.a; // Get "a"
deletions += w.d; // Get "d"
});
});
JSON:
[
{
"total": 2,
"weeks": [
{
"w": 1214092800,
"a": 0,
"d": 0,
"c": 0
},
{
"w": 1474761600,
"a": 0,
"d": 0,
"c": 0
},
{
"w": 1476576000,
"a": 0,
"d": 0,
"c": 0
}
],
"author": {
"login": "ramiro"
}
}
]
Try this it will work :
JSON :
var data = [
{
"total": 2,
"weeks": [
{
"w": 1214092800,
"a": 0,
"d": 0,
"c": 0
},
{
"w": 1474761600,
"a": 0,
"d": 0,
"c": 0
},
{
"w": 1476576000,
"a": 0,
"d": 0,
"c": 0
}
],
"author": {
"login": "ramiro"
}
}
];
1. Using for in loop
var weekData = data[0].weeks;
for (var i in weekData) {
console.log(data[0].weeks[i].a,data[0].weeks[i].d,data[0].weeks[i].c);
}
2. using Array map method
var weekData = data[0].weeks;
var returnData = weekData.map(function(e) {
return {
a: e.a,
d: e.d,
c: e.c
}
})
console.log(returnData);
Working fiddle : https://jsfiddle.net/ry49dz61/1/
You could use array method map and reduce. jQuery is not quite necessary.
var retrieved = data.map(function(v) {
var ret = v.weeks.reduce(function(a, b) {
return {
a: a.a + b.a,
d: a.d + b.d,
c: a.c + b.c
}
})
ret.login = v.author.login
return ret
})

Parse the JSON data in javascript

I Have following JSON data, I need to iterate this data based on Keytype in JAVASCRIPT.
It should return record from only the passed key code.
Say i need record from 438 means it should give me only following data.
(ex:"K": "43800001", "D": "Data1")
{
"GroupCode": {
"PickType": [
{
"#KeyType": "438",
"R": [
{
"K": "43800001",
"D": "Data1"
}
]
},
{
"#KeyType": "439",
"R": [
{
"K": "43900001",
"D": "Data2"
}
]
},
{
"#KeyType": "440",
"R": [
{
"K": "44000001",
"D": "Data3"
}
]
},
{
"#KeyType": "441",
"R": [
{
"K": "44100001",
"D": "Data4"
}
]
}
]
}
}
as I'm not good in java script and new to it, i haven't tried coding for this. Please help me in getting the data.
Let us say the above is stored in a variable obj. You can get the result via following
var result = obj.GroupCode.PickType.filter(function(item){
return item["#KeyType"] === "438"
}).map(function(item){
return item.R[0];
});
Please note, result is an array. If you have unique object against the condition then for that you will have to check the length of array and then extract the object i.e. result[0] or result.shift()
Working Fiddle here
function getByKeyType(keytype) {
for(i in f.GroupCode.PickType) {
if(f.GroupCode.PickType[i].KeyType == keytype) {
return f.GroupCode.PickType[i].R[0];
}
}
return null;
}
alert(getByKeyType(438).K)
alert(getByKeyType(438).D)
Try this
function getByKeyType(keytype) {
for(i in f.GroupCode.PickType) {
if(f.GroupCode.PickType[i].KeyType == keytype) {
return f.GroupCode.PickType[i].R[0];
}
}
return null;
}
Try a simple jquery each loop and a if:
jquery:
$.each(obj.GroupCode.PickType,function(i,v){
if (v["#KeyType"] == 438) {
console.log(v.R)//v.R[0];
}
});
javascript:
for(v in obj.GroupCode.PickType) {
if (v["#KeyType"] == 438) {
console.log(v.R)//v.R[0];
}
}

How to best "dynamically" make javascript have an conditional to find matches based on multiple possible key value pairs? Looking for a solution

How do I most efficiently structure a "conditions" object to find matches within a list of objects (consisting of key value pairs) and add them to a list of "matches?
I have a the following testList that contains multiple objects:
var testList = {
"A": "SUBA1",
"B": "SUBB2",
"C": "SUBC5",
},
{
"A": "SUBA2",
"B": "SUBB3",
"C": "SUBC1",
}
...
]
Right now my matchCondition with one condition is simple focused on one key and value:
var matchCondition = {"key": "A", val:"SUBA1"};
I want to shove any individual object in testList that matches my "matchCondition" into the "matchedList".
var matchedList = [];
So I do this now using "findMatches" function:
function findMatches(matchCondition, testList) {
var matchedList = [];
for(var i = 0; i < testList.length; i++) {
if(testList[matchCondition[key]] == testList[i][matchCondition[val]]) {
matchedList.push(testList[i]);
}
}
return matchedList;
}
My problem is, what if I want to match using multiple conditions something where for example "A" could be equal to "SUBA1" or "SUBA2", AND "B" is "SUBB2", AND "C" is "SUBB5":
Maybe the object could look like this?
var matchCondition = {
"A": ["SUBA1", "SUBA2"],
"B": ["SUBB2"],
"C": ["SUBC5"]
}
I am not sure what is the best way I can update my findMatches function to be more robust... or how do I best structure my "matchCondition" to be able to support multiple key values I want to match?
A proposal with some array methods like Array.prototype.filter() and Array.prototype.every() and Object.keys().
var testList = [{ "A": "SUBA1", "B": "SUBB2", "C": "SUBC5", }, { "A": "SUBA2", "B": "SUBB3", "C": "SUBC1", }],
matchCondition = { "A": ["SUBA1", "SUBA2"], "B": ["SUBB2"], "C": ["SUBC5"] };
function filter(data, condition) {
return data.filter(function (a) {
return Object.keys(condition).every(function (k) {
return ~condition[k].indexOf(a[k]);
});
});
}
document.write('<pre>' + JSON.stringify(filter(testList, matchCondition), 0, 4) + '</pre>');
You can iterate the mach condition object hasOwnProperty() and check its value meets the requirement.
var testList = [{
"A": "SUBA1",
"B": "SUBB2",
"C": "SUBC5",
}, {
"A": "SUBA2",
"B": "SUBB3",
"C": "SUBC1",
}];
var matchCondition = {
"A": ["SUBA1", "SUBA2"],
"B": ["SUBB2"],
"C": ["SUBC5"]
}
function findMatches(testList, matchCondition) {
return testList.filter(function(obj){
for (var key in matchCondition) {
if (matchCondition.hasOwnProperty(key) && obj.hasOwnProperty(key)) {
if( matchCondition[key].indexOf(obj[key]) == -1){
return false;
}
}else{
return false;
}
}
return true
});
}
snippet.log(JSON.stringify(findMatches(testList, matchCondition)))
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
A good read Javascript iterate object
It is not clear what you are expecting as a result, but here is a possible ES6 solution; based on your multiple condition matchCondition example.
'use strict';
var testList = [{
"A": "SUBA1",
"B": "SUBB2",
"C": "SUBC5",
}, {
"A": "SUBA2",
"B": "SUBB3",
"C": "SUBC1",
}];
var matchCondition = {
"A": ["SUBA1", "SUBA2"],
"B": ["SUBB2"],
"C": ["SUBC5"]
};
var matchedList = [];
for (let item of testList) {
let x = Object.create(null);
for (let key of Object.keys(matchCondition)) {
let val = item[key];
if (val) {
for (let sub of matchCondition[key]) {
if (sub === val) {
x[key] = sub;
break;
}
}
}
}
matchedList.push(x);
}
document.getElementById('out').textContent = JSON.stringify(matchedList, null, 2);
console.log(matchedList);
<pre id="out"></pre>
Or similar in ES5
'use strict';
var testList = [{
"A": "SUBA1",
"B": "SUBB2",
"C": "SUBC5",
}, {
"A": "SUBA2",
"B": "SUBB3",
"C": "SUBC1",
}];
var matchCondition = {
"A": ["SUBA1", "SUBA2"],
"B": ["SUBB2"],
"C": ["SUBC5"]
};
var matchedList = testList.reduce(function(acc, item) {
var x = Object.create(null);
Object.keys(matchCondition).forEach(function(key) {
var val = item[key];
if (val) {
matchCondition[key].some(function(sub) {
if (sub === val) {
x[key] = sub;
return true;
}
});
}
});
acc.push(x);
return acc;
}, []);
document.getElementById('out').textContent = JSON.stringify(matchedList, null, 2);
console.log(matchedList);
<pre id="out"></pre>
These are not your only possibilities, but you need to be clearer about your expectations and it would be good to see what you have tried, and where you are having a problem.

Categories