I have a very large data set that may contains thousands of records hierarchy is
records
->record1
->main_record
->minor_record
->fields
->record2
->main_record
->data_records
->fields_records
->fields
This hierarchy can be even more rested depending upon the input file and it may contains hundreds for records like record1 record2, here one thing I must mention that data is not sorted at level.
Now lets suppose I want to find fields in fields_record than XPath will be
record2/main_record/data_records/fields_records/fields
one way to find is to loop whole dataset and find desired record which is not affordable, the way I am using for searching data is:
function main() {
var dataset = getDataFromService();
getResult(dataset, xpath);
}
function getdataset(dataset, nametosearch) {
for (var i = 0; i < dataset.length; i++) {
if (dataset[i].name == nametosearch) {
return dataset[i];
}
}
}
function getResult(dataset, xpath) {
if (xpath.indexOf('/') > -1) {
var splitArray[] = xpath.split("/");
for (var i = 0; i < splitArray.length; i++) {
dataset = getdataset(dataset, splitArray[i]);
}
return dataset;
} else {
getdataset(dataset, xpath); //else part to get records at root level
}
}
With the above mentioned code I can get data I want to know is this way efficient? If not what would be the better option for getting data using XPath?
Try JSONPath.
Eaxmple:
Json:
{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}
Path:$.phoneNumbers[:1].type
Result:"iPhone"
Related
I am currently working on a website that imports JSON data and populates a table within HTML. In this instance the JSON file has already been parsed and exists as an JavaScript object.
I am having trouble iterating through the arrays within the object to try and add data with different key values to a single table row.
what I want to achieve is to have the names of each employee who works in a particular department to be present in a single row.
I started by creating an empty array outside my for loops.
I have iterated through the object using three separate for loops and appended the names of the employees to this empty array. After my loops i have let my now full array that contains the names equal to an empty array.
What i have been working on can be seen here https://jsfiddle.net/kn0y9g5d/
<div id="id01"></div>
<script>
const table =
{ "Employees":
[ { "Started" : "2016"
, "Department": "Engineering"
, "Employee":
[ { "id": "a101", "firstname": "Alan", "surname": "Arkin" }
, { "id": "a102", "firstname": "Geoff", "surname": "keegan" }
]
}
, { "Started" : "2016"
, "Department": "R&D"
, "Employee":
[ { "id": "a103", "firstname": "Michele", "surname": "Jones" }
, { "id": "a104", "firstname": "Peter", "surname": "Smith" }
]
}
]
}
var DepName =[];
var employeeNames =[];
let MyTable = document
.querySelector('#id01')
.appendChild(document.createElement('table'))
for (let StartDep of table.Employees)
{
for (let Employee of StartDep.Employee )
{
for (let Employee1 of StartDep.Employee ){
var name = Employee1.firstname + " " + Employee1.surname
employeeNames.push(name)
let nRow = MyTable.insertRow(-1)
, rCell = 0
nRow.insertCell(rCell++).textContent = StartDep.Started
nRow.insertCell(rCell++).textContent = StartDep.Department
nRow.insertCell(rCell++).textContent = employeeNames
}employeeNames=[];
}
}
let Rowhead = MyTable.createTHead().insertRow(-1)
'Started,Department,Name(s)'.split(',')
.forEach((T,i)=>Rowhead.insertCell(i).textContent=T)
</script>
what I expect to get using this code will be similar to this https://i.stack.imgur.com/Vgvlo.png
console.log(table);
const abc = [];
for(var j=0;j<2;j++)
{
const gh = [];
for(var i =0;i<2;i++)
{
let name = table.Employees[j].Employee[i].firstname+" "+table.Employees[j].Employee[i].surname
gh.push(name);
}
var totalName = gh.join();
abc.push(totalName);
}
console.log(table.Employees[0].Employee[0].firstname);
console.log(abc);
if you do this before appending this to table you should be able to get the result easily
i did it on my own so i cant give you any reference to look at.
hope this helps
I'm trying to show the coupons from a client that exist in one api. If one (or 'n') coupons exist inside of another api that counts the used coupons, i have to delete from the list that or those coupons used. The api of the used coupons response something like this:
{
"State": 200,
"Response": [
{
"IdInvoiceRequest": 104,
"Coupons": [
{
"IdCoupon": 77236,
"Code": "11#E5ZQHZ-GNH"
},
{
"IdCoupon": 77237,
"Code": "12#WM96FY-NGE"
},
{
"IdCoupon": 77239,
"Code": "14#BH92BA-E6N"
},
{
"IdCoupon": 77240,
"Code": "15#FWXNR4-XHP"
},
{
"IdCoupon": 77241,
"Code": "16#7FK5F8-TKM"
}
]
},
{
"IdInvoiceRequest": 143,
"Coupons": [
{
"IdCoupon": 77238,
"Code": "13#BN5MZB-VJ9"
}
]
}
],
"Message": "Informacion correcta",
"TotalRows": 0,
"IsCorrect": true}
The problem comes when i try to eliminate the used coupons. My code so far:
function validExist() {
vm.getSelected =
couponExist.get({
idOrder: vm.idOrder
}).$promise.then(function(data) {
for (var i = 0; i < data.Response.length; i++) {
data.Response[i].Select = vm.exist;
console.log(vm.exist);
}
vm.otherF = vm.coupons
for (var i = 0; i < data.Response.length; i++) {
data.Response[i].Select = vm.isHere;
console.log(vm.isHere);
}
if (vm.exist == vm.isHere) {
vm.coupons.splice(vm.coupons.IdCoupon, i++);
};
});
}
When splice acts, only eliminate the very first coupon, but the others still the same, even when all the coupons are inside of the used coupon list. What can i do to delete all the coupons? I've heard that a way to do this is using 'forEach' o a few 'for', but i don't see the light (sighs).
Can you help me?
Thanx in advance.
Array.prototype.splice takes a start index and the number of items to remove from the array. I'm not sure what the other parts of your code are supposed to be doing, but here's an example of how you'd look for items from one array and remove them from a second array:
var existingCoupons = [
{ IdCoupon: 111 },
{ IdCoupon: 222 },
{ IdCoupon: 333 },
{ IdCoupon: 444 },
{ IdCoupon: 555 }
];
var simulatedResponse = [{
IdInvoiceRequest: "abc",
Coupons: [
{ IdCoupon: 222 },
{ IdCoupon: 444 }
]
},{
IdInvoiceRequest: "def",
Coupons: [
{ IdCoupon: 555 }
]
}];
//Loop through the invoices in the response
for(var i=0; i<simulatedResponse.length; i++){
//Loop through the coupons in the invoice
for(var j=0; j<simulatedResponse[i].Coupons.length; j++){
//Loop through the existing coupons
for(var k=0; k<existingCoupons.length; k++){
//If the unique identifier matches...
if(existingCoupons[k].IdCoupon == simulatedResponse[i].Coupons[j].IdCoupon){
//Splice one existing coupon out of the array at the current index
existingCoupons.splice(k, 1);
break;
}
}
}
}
console.log(existingCoupons)
Let's add some clarity to the conceptual definition of the problem you are trying to solve, then select the actual programmatic implementation.
It seems you have 2 lists and the goal is to delete all entries from the first lists which exists in a second list. One possible and rather straightforward solution to this problem would be creating a third empty list and then using 2 for iterative loops (an outer for the first list and inner for the second one) dynamically add only entries from the first list which doesn't exist in the second one. In addition to the obvious simplicity, this approach will also provide near optimal computational performance.
Hope this may help.
I am having many such entries in my json data. The "type" consists of tw attributes i.e. income and expense. How to print the "label" which have type="expense" in using JavaScript.
This json data below is just an example.
Check the image to get a better idea of json data.
"expenses_veterinary":{
label:"Veterinary, breeding, and medicine"
name:"expenses_veterinary"
total:0
type:"expense"
}
console.log($ctrl.gold_standard_categories); prints all the json data.
I tried the code written below but its not working.
if($ctrl.gold_standard_categories.name.type=expense){
console.log($ctrl.gold_standard_categories.label);
}
It prints all the data because of the single equals sign in your if statement.
It means you are always trying to assign the value "expense" to your type property and so the if statement will always evaluate to true.
What you are intending to do is compare the values, not assign a value.
https://jsfiddle.net/yxL4rpj2/
assume that in var money you store the json response
var grouppedMoney = {
expenses: [],
incomes: []
};
for(var i = 0; i <= money.length - 1; i++){
for(moneyType in money[i]){
var _typeString = money[i][moneyType].type == 'expense' ? 'expenses' : 'incomes';
grouppedMoney[_typeString].push(money[i][moneyType]);
}
}
Here is the basic example.Iterate over your object and see type value is equal to expense then print the label value.
var data = {
"expenses_veterinary":{
"label":"Veterinary, breeding, and medicine",
"name":"expenses_veterinary",
"total":0,
"type":"income"
},
"expenses_car":{
"label":"bus and truck",
"name":"expenses_car",
"total":0,
"type":"expense"
}
};
for (var property in data) {
if (data.hasOwnProperty(property)) {
// do stuff
if(data[property]['type']=='expense'){
console.log(data[property]['label']);
}
}
}
It seems you are using AngularJS ($ctrl) so you may consider using either native angular filters or custom filter to do this.
BTW, using vanilla JS, this simple loop will work :
for(var key in jsonData) {
if("expense" === jsonData[key]["type"]) {
console.log(jsonData[key]["label"]);
}
}
Sample snippet
var jsonData = {
"expensesigoods": {
"name": "expenses_goods",
"label": "Cost of goods sold",
"type": "expense",
"total": 0
},
"expensesicar": {
"name": "expenses_car",
"label": "Car and truck expenses",
"type": "expense",
"total": 0
},
"expensesichemicals": {
"name": "expenses_chemicals",
"label": "Chemicals",
"type": "expense",
"total": 0
},
"expensesiconservation": {
"name": "expenses_conservation",
"label": "Conservation expenses",
"type": "other",
"total": 0
}
}
for(var key in jsonData) {
if("expense" === jsonData[key]["type"]) {
console.log(jsonData[key]["label"]);
}
}
Try Array.filter() method to filter the data based on type="expense".
Working Fiddle
var obj = {
"expenses_goods":{
"label":"expenses_goods",
"name":"expenses goods",
"total":0,
"type":"income"
},
"expenses_cars":{
"label":"expenses_cars",
"name":"expenses cars",
"total":0,
"type":"expense"
},
"expenses_veterinary":{
"label":"expenses_veterinary",
"name":"expenses veterinary",
"total":0,
"type":"income"
}
};
var res = Object.keys(obj).filter(item => { return obj[item].type == 'expense' });
for (var i in res) {
document.getElementById("result").innerHTML = obj[res[i]].label;
}
<div id="result">
</div>
Let's say I have the next JSON file:
{
"shows": [
{
"name": "House of cards",
"rating": 8
},
{
"name": "Breaking bad",
"rating": 10
}
]
}
I want to access the rating of a show, by it's name. Something like this:
var rating = data.shows["House of cards"].rating;
Is this possible? Or something similar?
Thanks a lot!
You won't have such hash-style access just by deserializing that JSON sample.
Maybe you might be able to re-formulate how the data is serialized into JSON and use object literals even for shows:
{
"shows": {
"House of cards": {
"rating": 8
}
}
}
And you can still obtain an array of show keys using Object.keys(...):
Object.keys(x.shows);
Or you can even change the structure once you deserialize that JSON:
var x = { shows: {} };
for(var index in some.shows) {
x.shows[some.shows[index].name] = { rating: some.shows[index].rating };
}
// Accessing a show
var rating = x.shows["House of cards"].rating;
I suggest you that it should be better to do this conversion and gain the benefit of accessing your shows using plain JavaScript, rather than having to iterate the whole show array to find one.
When you use object literals, you're accessing properties like a dictionary/hash table, which makes no use of any search function behind the scenes.
Update
OP has concerns about how to iterate shows once it's an associative array/object instead of regular array:
Object.keys(shows).forEach(function(showTitle) {
// Do stuff here for each iteration
});
Or...
for(var showTitle in shows) {
// Do stuff here for each iteration
}
Update 2
Here's a working sample on jsFiddle: http://jsfiddle.net/dst4U/
Try
var rating = {
"shows": [
{
"name": "House of cards",
"rating": 8
},
{
"name": "Breaking bad",
"rating": 10
}
]
};
rating.shows.forEach(findsearchkey);
function findsearchkey(element, index, array) {
if( element.name == 'House of cards' ) {
console.log( array[index].rating );
}
}
Fiddle
var data = {"shows": [{"name": "House of cards","rating": 8},{"name": "Breaking bad","rating": 10}]};
var shows = data.shows;
var showOfRatingToBeFound = "House of cards";
for(var a in shows){
if(shows[a].name == showOfRatingToBeFound){
alert("Rating Of "+ showOfRatingToBeFound+ " is " +shows[a].rating);
}
}
I've been trying to convert JSON like this into something that d3 can work with but I have been having a bit of trouble. Here's the example JSON
[{
"name" : "MATH210",
"work" : {
"assessment1" : {
"mark" : 65,
"weight" : 40
},
"assessment2" : {
"mark" : 65,
"weight" : 60
}
},
"overallMark" : 95
},
{
"name" : "MATH215",
"work" : {
"assessment1" : {
"mark" : 67,
"weight" : 30
},
"assessment2" : {
"mark" : 65,
"weight" : 45
},
"exam" : {
"mark" : 72,
"weight" : 25
}
},
"overallMark" : 85
},
{
"name" : "MATH220",
"work" : {
"assessment1" : {
"mark" : 65,
"weight" : 50
},
"assessment2" : {
"mark" : 65,
"weight" : 50
}
},
"overallMark" : 75
}]
I'm quite new to d3 but all the examples I've read and worked through have had data in the form of arrays so that's what my first approach focused on.
I'll post a little bit of code so you can better understand what I've done. So I first create an array containing module objects from the JSON using code like this
var count = 0;
// loop through json and instantiate each
// module and store in the modules array
$.each(json, function(i, item) {
progress.modules[count] = new Module( i , item );
count++;
});
Then I use lots of nested for/in loops to extract the data I want and store them in lots of arrays for each module, each module has 3 different arrays.
// Arrays that will hold all the broken down data
this.workNames = [], this.marks = [], this.weights = [];
This approach works but won't be appropriate for a lot of data.
All I want to do is draw some pie graphs based on overall marks and their weights and a scatter graph. From what I have read elsewhere on stack overflow and across the web I have a feeling that there is a much more graceful way to take this data and transform it into something that d3 can work with.
Maybe by using d3.nest() like this
D3 JSON data conversion
Does anybody have any ideas how I can transform this JSON to work well with d3 without using the approach above?
Thanks in advance :)
Let's look at a sub-task of the overall conversion. Consider this bit of data you have, which is in the form of an object (aka hash) of objects:
{
"assessment1" : {
"mark" : 67,
"weight" : 30
},
"assessment2" : {
"mark" : 65,
"weight" : 45
},
"exam" : {
"mark" : 72,
"weight" : 25
}
}
Most likely, what you want to transform it into is this array of objects:
[
{
"id": "assessment1"
"mark" : 67,
"weight" : 30
},
{
"id": "assessment2"
"mark" : 65,
"weight" : 45
},
{
"id" : "exam"
"mark" : 72,
"weight" : 25
}
]
So, if the original data was assigned to a var named work, then this is how you'd turn it into the array:
var workAsArray = []; // This will be the resulting array
for(var key in work) {
var entry = work[key]; // This will be each of the three graded things
entry.id = key; // e.g. "id": "assessment1"
workAsArray.push(entry)
}
This approach could also apply to the outer layer of data that contains this "work" array, and then the code snippet from above would be nested inside an outer loop.
Hope this helps....
P.S.
d3.nest is not going to help you in this case because it does sort of the opposite of what you're asking. It helps convert an array of data into a hash.
Here is a small converter that I made it changes any JSON to d3 format:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
//Eample JSON
var complexJson = {
"problems": [{
"Diabetes":[{
"medications":[{
"medicationsClasses":[{
"className":[{
"associatedDrug":[{
"name":"asprin",
"dose":"",
"strength":"500 mg"
}],
"associatedDrug#2":[{
"name":"somethingElse",
"dose":69,
"strength":"500 mg"
}]
}],
"className2":[{
"associatedDrug":[{
"name":"asprin",
"dose":"",
"strength":"500 mg"
}],
"associatedDrug#2":[{
"name":"somethingElse",
"dose":"",
"strength":"500 mg"
}]
}]
}]
}],
"labs":[{
"missing_field": "missing_value",
"boolean_field": true
}]
}],
"Asthma":[{}]
}]};
//Test if we should dig deeper
function hasJsonStructure(str) {
if (typeof str === 'string') return false;
try {
return Object.prototype.toString.call(str) === '[object Object]' || Array.isArray(str);
} catch (err) {
return false;
}
};
//Parse and convert object recursive
function walk2(obj2,level) {
var mytempCH = [];
var outer = [];
for (var key in obj2){
var value = obj2[key];
if(hasJsonStructure(value)){
//has children
var mytempCH2 = new Object();
mytempCH2.name = key;
mytempCH2.children = walk2(value,level+1);
outer.push(mytempCH2);
}else{
outer.push({"name": key + ": " + value, "value": level})
}
}
return outer
}
//Preapare Object Root
var myNewObj = new Object();
myNewObj.name = "ConvertedObj";
myNewObj.children = [];
var level = 1;
//Start work
myNewObj.children = walk2(complexJson,1);
//Output text to html
document.getElementById("demo").innerHTML = JSON.stringify(myNewObj); + "<br>";;
</script>
</body>
</html>