I am retrieving JSON from a live streaming data.
For the first call I am getting dataset array with time and value. But in the second JSON dataset array is empty. I want to check if dataset array contains time key.
Retrieved JSON after first call:
{
"activities-heart-intraday": {
"dataset": [{
"time": "00:00:00",
"value": 91
}, {
"time": "00:01:00",
"value": 92
}, {
"time": "00:02:00",
"value": 92
}],
"datasetInterval": 1,
"datasetType": "second"
}
}
Retrieved JSON after second call:
{
"activities-heart-intraday": {
"dataset": [],
"datasetInterval": 1,
"datasetType": "second"
}
}
I am doing
var value = JSON.parse(data);
if (value.hasOwnProperty('time')) {
console.log("here");
}
to check if time key exists in the JSON, but it's not working.
How can I check if a particular key exists in the array in json?
Firstly you have to check that dataset is not an empty array. Then check that time is defined.
This can be solved with:
if (dataset[0] !== undefined && dataset[0].time !== undefined)
or just:
if (dataset[0] && dataset[0].time)
If you want to iterate through the array:
dataset.forEach(function (data) {
if (data.time) {
// your code
}
});
the data has a dataset array so we need to first check if the array is there and then if one of the arrays members has the time property
if( data.hasOwnProperty('dataset') && data.dataset.length != 0){
if( data.dataset[0].hasOwnProperty('time')){
console.log('true');
}
}
Since in JS you can not natively set and access object properties those with a "-" character in it by dot notation you have define them as strings and use bracket notation instead to set and access them. So you can make a check like this
data["activities-heart-intraday"].dataset.length > 0 && data["activities-heart-intraday"].dataset.every(e => !!e.time);
I can't really tell what data from your question is supposed to be but if it is the whole JSON object, then the most simple way is this:
if(data["activities-heart-intraday"]["dataset"][0]["time"])
console.log('time is set)
But beware! If for example the dataset is not set, you'll get an error that you are trying to get time key from undefined and the code will crash. I'd recommend using simple recursive function like this:
function is_there_the_key(json, keys){
if(keys.length == 0)
return true //we used the whole array, and every key was found
let key = keys.shift() //pop(get and remove) the first string from keys
if(!json[key]){
console.log(key + ' not found')
return false //one of the keys doesn't exist there
}
return is_there_the_key(json[key], keys)
}
Whether you return true or false, both of them will make their way up to the surface.
As the json parameter you pass the json you want to search in.
As the keys parameter you pass an array (mostly strings) of the keys in order they should go.
For example:
if(is_there_the_key(data, ["activities-heart-intraday", "dataset", 0, "time"])
//we found the key, do something here
Related
I am currently making a call to a service which sends a response as an array of objects with name value pairs. An example of this can be seen below. There could be any amount of these name value pairs in any order but I just want to access the value for the name "name2". Is there an efficient way other than looping through each object and checking the name to obtain the corresponding value for name2?
[{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}]
So from the above data set I would want an efficient way to search for name2 and get the corresponding value "value2".
Thanks
Unless you know the specific index of the object with the name name2 no.
You'll need to iterate until you find that name then you can bail out.
e.g.
var jsonData = [{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}];
for(var i=0;i<jsonData.length;i++){
if(jsonData[i]['name'] == 'name2'){
console.log('The value is: ' + jsonData[i]['value']);
break;
}
}
Note that if you don't need to support Internet Explorer, you can use the Array.find() method to simplify this.
if you don't want to iterate over the array manually you can use lambda expression as the following
a =[{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}] ;
//get the items that match your criteria
a.filter(item=>item.name=="name2")
//get those items' values
a.filter(item=>item.name=="name2").map(item=>item.value)
//get the first value (if you know that it's only one item that will match)
a.filter(item=>item.name=="name2").map(item=>item.value)[0]
You can use Array#find method.
var arr = [{
"name": "name1",
"value": "value1"
}, {
"name": "name2",
"value": "value2"
}];
// get the object containing name as `name2`
var obj = arr.find(function(v) {
return v.name === 'name2';
});
// get value property if object is defined
var res = obj && obj.value;
console.log(res)
This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
How to find object in array by property in javascript?
(3 answers)
Closed 5 years ago.
I have following json
var dictionary = [{"key":"Math","value":"20"},{"key":"History","value":"10"},{"key":"Chemistry","value":"12"}]
I can access for instance the second element of the array like this:
dictionary[1].value
it returns 10 which is the score of the History subject.
What I'm looking for is the way so that I can access it by the word "History" itself, I mean I need a code like this:
dictionary["History"].value
How can I achieve that?
Ok, so here is a hack. You can use Array as an Object and insert any key you want. You can apply forEach to it and bind keys with properties like below.
var dictionary = [{"key":"Math","value":"20"},{"key":"History","value":"10"},{"key":"Chemistry","value":"12"}]
dictionary.forEach(function(item) {
dictionary[item.key] = item;
});
console.log(dictionary["History"].value);
Note: This is just a Hack and will fail in case of duplicate entries.
Edited
Solution in case of duplicate keys
var dictionary = [{
"key": "Math",
"value": "20"
}, {
"key": "History",
"value": "10"
}, {
"key": "Chemistry",
"value": "12"
}, {
"key": "Chemistry",
"value": "13"
}]
dictionary.forEach(function(item) {
if (dictionary[item.key] && !Array.isArray(dictionary[item.key])) {
dictionary[item.key] = [dictionary[item.key]];
dictionary[item.key].push(item);
} else if (dictionary[item.key] && Array.isArray(dictionary[item.key])) {
dictionary[item.key].push(item);
} else {
dictionary[item.key] = item;
}
});
console.log(dictionary["Chemistry"]);
By using find() to iterate over your array.
From MDN Array.prototype.find():
The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
const dictionary = [{"key":"Math","value":"20"},{"key":"History","value":"10"},{"key":"Chemistry","value":"12"}]
const result = dictionary.find(item => {
// if this returns `true` then the currently
// iterated item is the one found
return item.key === 'History'
})
console.log(result)
There's more than one way to do this but this one is the most straightforward and succinct.
Try this:
var dictionary = [
{"key":"Math","value":"20"},
{"key":"History","value":"10"},
{"key":"Chemistry","value":"12"}
];
function getValue(searchKey) {
var retVal;
dictionary.some(item => {
if (item.key === searchKey) {
retVal = item.value;
return true;
}
});
return retVal;
}
console.log(getValue('History'));
If goes through your array of objects and finds the object that matches its key to your searchKey and returns the result.
Or you can convert your array of objects into a single object and then reference it directly:
var dictionary = {};
[
{"key":"Math","value":"20"},
{"key":"History","value":"10"},
{"key":"Chemistry","value":"12"}
].forEach(item => {dictionary[item.key] = item.value;});
console.log(dictionary.History);
I have an object that I need to transform into an array. Here is the code I have already:
for (var key in categoryData[p]) { // categorydata is an object, the "p" is because this is taking place in a loop (array of objects)
if (categoryData[p].hasOwnProperty(key)) {
var objToArray = $.map(categoryData[p], function(value, key) {
return [value];
});
}
}
Right now, this is returning:
0 : value
1 : value
2 : value
I want it to return:
Key : Value
Key : Value
Key : Value
But I haven't found a way to do this with my data. Any direction would be greatly appreciated!
Edit: Adding more information:
I want to sort from the highest to lowest value. For clarification, I want the data to look like this:
(key) (object)
"ABC" : 8
"DEF" : 7
"GHI" : 5
I am putting it into an array to begin with because I can't sort the values when they're in an object (as far as I know).
My data is fairly complex, in a CSV file, but the idea of it is:
ABC, DEF, GHI
8 , 7 , 5
Associative arrays aren't a thing in javascript. You can either have arrays denoted by [] with 0 based numeric indices, or objects denoted by {} that can store key-value pairs. The latter construct can be used as replacement to associative arrays (ie add arbitrary keys and values to it), but they cannot be treated like arrays.
What you want in this case is what you already have - a key/value store, except it's called an object.
edit
If you just want to sort the data regardless of datatypes
You can split your object into multiple objects with a single key-value pair, then create an array from these objects and sort them any way you like using Array.sort(). Here's a quick example of splitting your provided data into objects:
var originalData = {
"ABC" : 8,
"DEF" : 7,
"GHI" : 5,
},
sortableArray = [];
for (key in originalData) {
sortableArray.push({
"key" : key,
"value" : originalData[key]
});
}
This creates a new object and appends it to our sortable [] array. To sort it according to its original value, you need to supply a comparator function that accesses the value property of the objects.
sortableArray.sort(function(a,b) {
return a.value - b.value;
});
This should return an array of objects ordered by the value property of each object in ascending order. Simply switch a and b around to get a descending order sort.
Hope this helps!
The best approach to sort your data is to map your object into an array to look like this:
[
{
"key": someKey
"value": someValue
},
{
"key": someOtherKey
"value": someOtherValue
},
//...
]
using this code:
var objToArray = $.map(categoryData[p], function(value, key) {
return {"key": key, "value": value};
});
And then sort it using this code:
objToArray.sort(function(a, b) {
// if the values are numbers (otherwise you have to change this to addapt to your dataType)
return b.value - a.value; // to sort from highest to lowest or a.value - b.value to sort from lowest to highest
});
And then you can use it like:
objToArray[0].key; // to get the key of the first item
objToArray[3].value; // to get the value of the 4-th item
// ...
You can loop through them as well (for(var i = 0; i < objToArray.length; i++)...).
In ES6, Object.entries(a).sort((a, b) => a[1] < b[1] )
This will give you something like this
[
["ABC", 8]
["DEF", 7]
["GHI", 5]
]
the .entries step gives you the list of pairs and the .sort step sorts them by their second value
I have an object with two types of data: Array and String:
{
"livingroom": [
{
"app": "",
"name": "s1",
"thumbnail": "https://storage.googleapis.com/peterbucket/istagingViewer/sigstaging.com.tw/Cuiti/study/web/thumb_floorplan1.jpg"
}
],
"study": [
{
"app": "",
"name": "s0",
"thumbnail": "https://storage.googleapis.com/peterbucket/istagingViewer/sigstaging.com.tw/Cuiti/study/web/thumb_floorplan3.jpg"
}
],
"outdoor": [],
"id": "-KF28-_Vdve-u3498eQ1",
"name": "Cuiti"
}
Right now I'm looping through all the values, and I want to return only the first non-empty array (in this case the value of livingroom).
// Template
<div v-for="value in object" v-if="isFirstNonEmptyArray(value, object)">
// JavaScript
isFirstNonEmptyArray (value, object) {
if (value instanceof Array) {
if (value.length > 0) {
// What to do here?
}
}
},
But as you can see I'm stuck after checking that the value is not empty. What should I write next?
This is a tricky question because Javascript objects do not have an ordering on their properties.
In other words, it is very difficult to return the first such property with empty value because no loop through the object properties is guaranteed to hit them in the same order. As a corollary, it is therefore impossible to return true if that property is the first such value in the object, so your problem cannot be solved as stated :)
If you have only one property with a non-empty length, the best you can do is the following:
function FirstNonEmptyArray(object) {
for (var property in object) {
if (object.hasOwnProperty(property) && (object[property] instanceof Array)) {
if (object[property].length > 0) {return property;}
}
}};
If you have multiple properties that have non-empty length, well, iteration order through an object is not guaranteed. Any one of those properties could be returned.
It's much better to append property names to an array if they have non-zero length and then do with them as you will:
function AllNonEmptyArrays(object) {
var array = []
for (var property in object) {
if (object.hasOwnProperty(property) && (object[property] instanceof Array)) {
if (object[property].length > 0) {array.push(property);}
}
return array;
}};
Hope this code will be useful.
Js obejct does not guarantee the ordering of its key.So finding out only those keys which are array and non empty
var _localArray = [] // Use to store non empty array
for(var keys in a){ // Iterating over object. a is the object
// Checking if the current key is an array & it's length is >= 1
if(Object.prototype.toString.call(a[keys] ) === '[object Array]' && a[keys].length>=1) {
_localArray.push(a[keys]); // push the key in temp array
}
}
console.log(_localArray[0]); // will log the first non empty array
jsfiddle
I have a contact list that is returned to me in this very long form. It is getting returned Based on order of entry (the field outside the first set of brackets, indented). The problem I'm having is I want it to order alphabetically by displayName. Since that is in it's own array inside of the main one I'm having trouble getting the full array to reorder by it. Can anyone figure this out? Thanks. Oh and it's got to be done in JS.
{
"0":
{"id":1,"rawId":null,"displayName":"Person 1","name":null,"nickname":null,"phoneNumbers":[{"type":"mobile","value":"phonenumb53534r","id":0,"pref":false}],"emails":null,"addresses":null,"ims":null,"organizations":null,"birthday":null,"note":null,"photos":null,"categories":null,"urls":null},
"1":
{"id":2,"rawId":null,"displayName":"Person 2","name":null,"nickname":null,"phoneNumbers":[{"type":"mobile","value":"phonenumber535345","id":0,"pref":false}],"emails":null,"addresses":null,"ims":null,"organizations":null,"birthday":null,"note":null,"photos":null,"categories":null,"urls":null},
"2":
{"id":3,"rawId":null,"displayName":"Person 3","name":null,"nickname":null,"phoneNumbers":[{"type":"mobile","value":"phonenumber47474","id":0,"pref":false}],"emails":null,"addresses":null,"ims":null,"organizations":null,"birthday":null,"note":null,"photos":null,"categories":null,"urls":null}, goes on for a couple hundred rows
Objects in JavaScript are not ordinal by nature. If you have an array, you can work with that. Otherwise, you have to convert the outer part of the object into an array yourself:
var arrayOfObj = [];
for (item in obj) {
if (obj.hasOwnProperty(item)) {
arrayOfObj.push(obj[item]);
}
}
If you can do that before you even get the JSON, so much the better. Once you have that, you can just use the normal array .sort method
arrayOfObj.sort(function (a, b) {
if (a.displayName < b.displayName) {
return -1;
}
else if (a.displayName > b.displayName) {
return 1;
}
return 0;
});
http://jsfiddle.net/ZcM7W/
You'll need to parse that responseText into JSON. But since it's returned as an object literal you'll have to convert it to an array. Then you can sort it with a custom comparator function.
var json = JSON.parse(response),
data = [];
for (key in json) {
data.push(json[key]);
}
data.sort(function (a, b) {
return a.displayName > b.displayName;
});