Get first element in a for..in two dimension - javascript

i have a Json object that basicly is a array and in each array i want to iterate over the propertys, so i did something like this:
for(var x = 0;x<dados.feeds.length;x++){
for(var y in dados.feeds[x]){
console.log(dados.feeds[x][y]);
/*if(data == dataInicial){
console.log("a");
}*/
}
}
that console.log(dados.feeds[x][0]) gives me undefined, i just want the first element on each x row, how can i get it ?
json object dados
{
"channel":
{
"id": 9,
"name": "my_house",
"description": "Netduino Plus connected to sensors around the house",
"latitude": "40.44",
"longitude": "-79.996",
"field1": "Light",
"field2": "Outside Temperature",
"created_at": "2010-12-13T20:20:06-05:00",
"updated_at": "2014-02-26T12:43:04-05:00",
"last_entry_id": 6060625
},
"feeds":
[
{
"created_at": "2014-02-26T12:42:49-05:00",
"entry_id": 6060624,
"field1": "188",
"field2": "25.902335456475583"
},
{
"created_at": "2014-02-26T12:43:04-05:00",
"entry_id": 6060625,
"field1": "164",
"field2": "25.222929936305732"
}
]
}

The code as you have it runs fine, everything traces out, nothing is undefined (I tried it).
But, console.log[x][0] will trace undefined, because:
var x = 0;
var obj = feeds[x]; // this will be the first object from the feeds array.
console.log ( obj [ 0 ] );
You probably see it now; that will trace undefined, because that obj has no 0 property. It's an object with keys/values.
So this would work:
var each = 'created_at';
console.log ( obj [ each ] );
And this:
for ( var each in obj ) {
console.log ( each, obj [ each ] );
}

How is your data looks like? If it's similar to
var dados = {
feeds: [ {a: 'aa'}, {b: 'bb'} ]
}
then you can try this:
dados.feeds.forEach(feed => {
Object.keys(feed).forEach((key, index) => {
if(index === 0) { console.log(feed[key]) } // aa bb...
})
})
HTH

It should be console.log(dados.feeds[x].created_at);.

Although you shouldn't rely on Javascript object key order, here is a solution that will return the value of the first key in each entry in the feeds array;
var dados = {
"channel":
{
"id": 9,
"name": "my_house",
"description": "Netduino Plus connected to sensors around the house",
"latitude": "40.44",
"longitude": "-79.996",
"field1": "Light",
"field2": "Outside Temperature",
"created_at": "2010-12-13T20:20:06-05:00",
"updated_at": "2014-02-26T12:43:04-05:00",
"last_entry_id": 6060625
},
"feeds":
[
{
"created_at": "2014-02-26T12:42:49-05:00",
"entry_id": 6060624,
"field1": "188",
"field2": "25.902335456475583"
},
{
"created_at": "2014-02-26T12:43:04-05:00",
"entry_id": 6060625,
"field1": "164",
"field2": "25.222929936305732"
}
]
};
var con = document.getElementById('console');
for (var i = 0; i < dados.feeds.length; i++) {
var firstKey = Object.keys(dados.feeds[i])[0];
con.innerHTML += '<p>' + dados.feeds[i][firstKey] + '</p>';
}
/*
Prints;
2014-02-26T12:42:49-05:00
2014-02-26T12:43:04-05:00
*/
Here is a fiddle with the working code.

Related

Getting data with a similar key name in JavaScript

I have this data.
{"channel":
{
"id":*******,"name":"INA229 Measurement",
"description":"Test with INA229",
"latitude":"0.0",
"longitude":"0.0",
"field1":"Voltage",
"field2":"Current",
"field3":"Power",
"field4":"Temperature",
"created_at":"2022-04-07T08:40:24Z",
"updated_at":"2022-04-07T08:40:52Z",
"last_entry_id":3771},
"feeds":[]
}
How to take only values for field(x) keys to new data. The key of the name field(x) (field1, field2, field3 ..... field8) is dynamic and varies in the range from field1 to field8 keys. I don't know how many there will be in total, even when receiving data.
Iterate over data.channel with for/in, check to see if the key starts with the keyword and, if it does, add the value of that property to a new object using that key.
const data = { "channel": { "id": "", "name": "INA229 Measurement", "description": "Test with INA229", "latitude": "0.0", "longitude": "0.0", "field1": "Voltage", "field2": "Current", "field3": "Power", "field4": "Temperature", "created_at": "2022-04-07T08:40:24Z", "fieldTest": "Test", "updated_at": "2022-04-07T08:40:52Z", "last_entry_id": 3771 }, "feeds": [] };
const out = {};
for (const key in data.channel) {
if (key.startsWith('field')) {
out[key] = data.channel[key];
}
}
console.log(out);
Using Object#entries, get the key-value pairs of channel
Using Array#reduce, iterate over the latter while updating the resulting object
In each iteration, use String#match to check for the key format
const data = { "channel": { "id": "", "name": "INA229 Measurement", "description": "Test with INA229", "latitude": "0.0", "longitude": "0.0", "field1": "Voltage", "field2": "Current", "field3": "Power", "field4": "Temperature", "created_at": "2022-04-07T08:40:24Z", "updated_at": "2022-04-07T08:40:52Z", "last_entry_id": 3771 }, "feeds": [] };
const res = Object.entries(data.channel).reduce((acc, [key, value]) => {
if(key.match(/^field[1-8]$/)) {
acc[key] = value;
}
return acc;
}, {});
console.log(res);

How can I dynamically remove a parent in JSON with JS?

With some JavaScript, how can I transform a JSON from:
{
"d": {
"__count": "13",
"results": [
{
"__metadata": {
"id": "123"
},
"COAST": "East",
"STATUS": "done",
"COLOR": "blue",
}
]
}
}
TO
{
"__count": "13",
"data": [
{
"__metadata": {
"id": "123"
},
"COAST": "East",
"STATUS": "done",
"COLOR": "blue",
}
]
}
Basically removing the extra "d" parent and renaming results to data? I am using this in the context of vue-table in VueJS.
Assumed that you have the json saved in a variable 'data':
data = data.d
data.data = data.results
delete data.results
This function will do it.
function transform(json) {
var obj = JSON.parse(json);
obj.d.data = obj.d.result;
delete obj.d.result;
return JSON.stringify(obj.d);
}
One solution is to unserialize your JSON to have an object (JSON.parse()). Then to serialize only what you need (JSON.stringify()).
You can use a loop.
var res = [];
for(var k in jsonData){
res.push(jsonData[k]);
}
var jsonData = {
"d": {
"__count": "13",
"results": [
{
"__metadata": {
"id": "123"
},
"COAST": "East",
"STATUS": "done",
"COLOR": "blue",
}
]
}
};
console.log(jsonData);
var res = [];
for(var k in jsonData){
res.push(jsonData[k]);
}
console.log("result:");
console.log(res);

Turn array of objects into array of unique combinations of its properties

I have to extract specific data from an object. My code works but I wonder if I could improve it by using method like map or filter.
This is for no specific background just for personnel training. Also I am using Lodash library
function extractApi(data) {
var arrayOfTowns = [];
var arrayOfCityCode = [];
var result = [];
//looping throw the expected datas (cities and postcode)
for (var i = 0; i < data.features.length; i++) {
arrayOfCityCode.push(_.toString(data.features[i].properties.postcode));
arrayOfTowns.push(_.toString(data.features[i].properties.city));
//verify unique cities
arrayOfTowns = _.uniq(arrayOfTowns);
//pushing to a new array to have the expected result format
if (arrayOfTowns[i] != undefined && arrayOfCityCode != undefined){
result[i] = arrayOfCityCode[i] + " " + arrayOfTowns[i]
}
}
return result
}
//example with some datas
extractApi( {
"type": "FeatureCollection",
"limit": 20,
"version": "draft",
"licence": "ODbL 1.0",
"attribution": "BAN",
"features": [
{
"type": "Feature",
"properties": {
"importance": 0.6466,
"type": "municipality",
"adm_weight": 4,
"postcode": "43000",
"context": "43, Haute-Loire, Auvergne-Rhône-Alpes (Auvergne)",
"id": "43157",
"population": 18.8,
"x": 769600,
"y": 6438600,
"name": "Le Puy-en-Velay",
"citycode": "43157",
"label": "Le Puy-en-Velay",
"city": "Le Puy-en-Velay",
"score": 0.8769636363636364
},
"geometry": {
"coordinates": [
3.883955,
45.043141
],
"type": "Point"
}
},
{
"type": "Feature",
"properties": {
"importance": 0.0867,
"type": "municipality",
"adm_weight": 1,
"postcode": "43000",
"context": "43, Haute-Loire, Auvergne-Rhône-Alpes (Auvergne)",
"id": "43089",
"population": 3.6,
"x": 767600,
"y": 6438900,
"name": "Espaly-Saint-Marcel",
"citycode": "43089",
"label": "Espaly-Saint-Marcel",
"city": "Espaly-Saint-Marcel",
"score": 0.8260636363636362
},
"geometry": {
"coordinates": [
3.858597,
45.046041
],
"type": "Point"
}
},
],
"query": "43000"
}
)
The goal is to receive all data.features.properties.postcode and data.features.properties.city and push it to an array. For this example the expected result is ["43000 Le Puy-en-Velay", "43000 Espaly-Saint-Marcel"]. Cities in the result should be unique.
You can indeed use .map to get the results you desire:
const parsedCities = data.features
.map(f => `${f.properties.postcode} ${f.properties.city}`)
.filter((f, i, a) => a.indexOf(f) === i);
//["43000 Le Puy-en-Velay", "43000 Espaly-Saint-Marcel"]
You can find the documentation on Array.prototype.map() here.
One may use
Array.prototype.map() to extract necessary properties (citycode, city) into the string
Set to get rid of duplicates
const src = {"type":"FeatureCollection","limit":20,"version":"draft","licence":"ODbL 1.0","attribution":"BAN","features":[{"type":"Feature","properties":{"importance":0.6466,"type":"municipality","adm_weight":4,"postcode":"43000","context":"43, Haute-Loire, Auvergne-Rhône-Alpes (Auvergne)","id":"43157","population":18.8,"x":769600,"y":6438600,"name":"Le Puy-en-Velay","citycode":"43157","label":"Le Puy-en-Velay","city":"Le Puy-en-Velay","score":0.8769636363636364},"geometry":{"coordinates":[3.883955,45.043141],"type":"Point"}},{"type":"Feature","properties":{"importance":0.0867,"type":"municipality","adm_weight":1,"postcode":"43000","context":"43, Haute-Loire, Auvergne-Rhône-Alpes (Auvergne)","id":"43089","population":3.6,"x":767600,"y":6438900,"name":"Espaly-Saint-Marcel","citycode":"43089","label":"Espaly-Saint-Marcel","city":"Espaly-Saint-Marcel","score":0.8260636363636362},"geometry":{"coordinates":[3.858597,45.046041],"type":"Point"}},],"query":"43000"};
const uniqueCities = obj =>
[...new Set(obj.features.map(({properties:{city,citycode}}) => citycode+' '+city))]
console.log(uniqueCities(src));
.as-console-wrapper {min-height: 100%}

Javascript Push Product Info as Object to an Empty Array

I have an array of products would like to add all the product information as an object to an empty array.
var data = {
"Vegetables": [
{
"id": "1",
"title": "Peas",
"type": "Green",
},
{
"id": "2",
"title": "Carrots",
"type": "root",
}
],
"Protein": [
{
"id": "3",
"title": "Steak",
"type": "Meat",
},
{
"id": "4",
"title": "Eggs",
"type": "Dairy"
}
]}
I am able to push just the title to the empty result array with the following:
function getCategory() {
result = [];
for (let item in data) {
data[item].forEach(v => result.push(v.title));
}
document.write(result);
}
getCategory();
But I would like to be able to push all the product information as an object so I can do some formatting. For example:
var myObj= "" ;
myObj = "<div class='box'>" + title +"<br> "+ type + "</div>";
result.push(myObj); // push it to result[]
I am unsure how to adapt the body of the for loop to accommodate my object:
data[item].forEach(v => result.push(v.title + v.type)); // needs to be pushed as object.
Any help appreciated.
Cheers

How to iterate nested json object?

I have a nested JSON Object and i want to iterate that.
JSON Response
{
"specifications": {
"IP6": {
"name": "Devices",
"productSubType": "Device",
"productSpecificationType": "Phones"
}
},
"offers": {
"US-PRE-IPHONE-CASE": {
"path": "productDetails/IP6",
"familyData": {
"0": "Missing Family Level data Should be here"
},
"facets": [],
"type": [],
"offers": {
"US-PRE-HG-PH-IP6": {
"hashDigest": "cf23df2207d99a74fbe169e3eba035e633b65d94",
"offerName": "offerNameString",
"productName": "iPhone 6 Case Mate Naked Tough Case - Clear",
"productOfferings": {
"ratings": "4.5",
"noOfReviews": "2010"
},
"offerStatus": {},
"displayPriority": "100200",
"descriptions": {
"shortDescription": "Iphone Decription ",
"longDescription": "longDescriptionStri6 descriptionng",
"alternativeDescription": "alternativeDescriptionString",
"reprsentativeDescription": ""
},
"specifications": [
"someSpecificationId1"
],
"brand": "Apple",
"productType": "Device",
"productSubType": "Phone",
"offerType": "",
"offerSubType": "",
"compatibility": {},
"classification": [],
"images": {
"thumbanail": {
"imagePath": "http://s.tmocache.com/images/png/products/accessories/SUPM43270/SUPM43270-small.png"
}
},
"equipmentCharacteristics": {},
"offerVariants": {},
"type": "hard-good",
"offers": [],
"family": "IP6",
"pricePoints": {
"withServicePrice16GBNEW": {
"displayPriority": "1001",
"pricingMessage": "device price with service activation",
"price": "34.99",
"discounts": {}
}
},
"dynamicPricingData": {},
"inventoryData": {
"SKUGOLD16GBN": {
"availibility": "Pre-order now!",
"availableTimeline": ""
}
}
}
}
}
}
}
Now as you see there are nested JSON objects in this and I want the value of
productName
shortDescription
imagePath
availibility
What I have tried is
function change(){
var acc = response; //response is JSON Object mentioned above
var accArray = [];
var accArray1 = [];
for (var obj in acc.specifications){
accArray.push(obj);
}
alert(accArray[0]);
for (var obj in accArray[0].offers){
accArray1.push(obj);
}
alert(accArray1[0]);
}
I am able to get the first object the first alert output is
IP6
but when I am trying to iterarte the IP6 object in same way the output is
undefined
I want to fetch all the 4 values as I mentioned above and then put them in an array.
As Grundy pointed out in his comment, obj in your code is the key of properties/items in specifications object. That means 'obj' is just a string.
To get reference to the object, change your code as below:
for(var obj in acc.specifications){
accArray.push(acc.specifications[obj]);
}
For better readability change obj to key
You can use for..in loop and recursion.
function find(obj, fieldName){
if(Array.isArray(obj)){
for(var i=0, len=obj.length;i<len;i++){
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}else{
if(typeof obj !== "object") return {isFind:false};
for(var i in obj){
if(i === fieldName) return {isFind:true, value:obj[i]};
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}
return {isFind:false};
}
this function return object with field isFind for case when available value can be null or undefined
var obj = {
"specifications": {
"IP6": {
"name": "Devices",
"productSubType": "Device",
"productSpecificationType": "Phones"
}
},
"offers": {
"US-PRE-IPHONE-CASE": {
"path": "productDetails/IP6",
"familyData": {
"0": "Missing Family Level data Should be here"
},
"facets": [],
"type": [],
"offers": {
"US-PRE-HG-PH-IP6": {
"hashDigest": "cf23df2207d99a74fbe169e3eba035e633b65d94",
"offerName": "offerNameString",
"productName": "iPhone 6 Case Mate Naked Tough Case - Clear",
"productOfferings": {
"ratings": "4.5",
"noOfReviews": "2010"
},
"offerStatus": {},
"displayPriority": "100200",
"descriptions": {
"shortDescription": "Iphone Decription ",
"longDescription": "longDescriptionStri6 descriptionng",
"alternativeDescription": "alternativeDescriptionString",
"reprsentativeDescription": ""
},
"specifications": [
"someSpecificationId1"
],
"brand": "Apple",
"productType": "Device",
"productSubType": "Phone",
"offerType": "",
"offerSubType": "",
"compatibility": {},
"classification": [],
"images": {
"thumbanail": {
"imagePath": "http://s.tmocache.com/images/png/products/accessories/SUPM43270/SUPM43270-small.png"
}
},
"equipmentCharacteristics": {},
"offerVariants": {},
"type": "hard-good",
"offers": [],
"family": "IP6",
"pricePoints": {
"withServicePrice16GBNEW": {
"displayPriority": "1001",
"pricingMessage": "device price with service activation",
"price": "34.99",
"discounts": {}
}
},
"dynamicPricingData": {},
"inventoryData": {
"SKUGOLD16GBN": {
"availibility": "Pre-order now!",
"availableTimeline": ""
}
}
}
}
}
}
}
function find(obj, fieldName){
if(Array.isArray(obj)){
for(var i=0, len=obj.length;i<len;i++){
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}else{
if(typeof obj !== "object") return {isFind:false};
for(var i in obj){
if(i === fieldName) return {isFind:true, value:obj[i]};
var nested = find(obj[i],fieldName);
if(nested.isFind) return nested;
}
}
return {isFind:false};
}
var result = ['productName','shortDescription','imagePath','availibility'].map(function(el){ return find(obj,el).value});
document.getElementById('r').innerHTML = JSON.stringify(result,null,2);
<pre id='r'></pre>
Your json code is a complex data binding structure. It same like c# complex data binding. So you need to call the obj by through it call name.
for eg:
var data = {"ex":{"a":{"a1":"a1","a2":"a2"},"b":{"b1":"b1","b2":"b2"}}}
so data is a class and it includes "ex" object
data returns =>Object {ex: Object}
if you need to access "a" or "b" object means , you need to access through the"ex" object.
for eg:
data.ex.a => Object {a1: "a1", a2: "a2"}
in your code
for(var obj in acc.specifications){
accArray.push(obj);
}
obj only push 1st element of acc.sppectification object.
So please try this.
foreach(var obj acc.specification){
arr1.push(acc.specification[obj])
}
foreach (var obj acc.offers){
arr2.push(acc.offers[obj])
}

Categories