jQuery read data object and wait $.each is done - javascript

This is my data object
{
"teachers":{
"0":{
"info":{
"id":"1",
"age":"22",
"driverlicense":"yes"
}
},
"1":{
"info":{
"id":"2",
"age":"51",
"driverlicense":"yes"
}
},
"2":{
"info":{
"id":"1",
"age":"25",
"driverlicense":"no"
}
}
}
}
What I try to read is the info object, and take the information from there.
My code
$.each(data.teachers, function(item) {
if(item.info.age < '25'){
// stores in array
yTeachers[item.info.id] = item.info.age;
}
});
But it gives me undefined back.
Is it possible to read the array teachers if the $.each is done? Sometimes it is still running when I run another function. Maybe use something like promise?

This should work for you to store ages > 25 on yTeachers as an object.
var json = {
"teachers": {
"0": {
"info": {
"id": "1",
"age": "22",
"driverlicense": "yes"
}
},
"1": {
"info": {
"id": "2",
"age": "51",
"driverlicense": "yes"
}
},
"2": {
"info": {
"id": "1",
"age": "25",
"driverlicense": "no"
}
}
}
};
var yTeachers = [];
$.each(json.teachers, function(index,item) {
var id = item.info.id;
var age = item.info.age;
if(age < 25){
// push it in array
yTeachers.push({id:age});
}
});
console.log(yTeachers);

Use this for reference check fiddle:
var data = {
"teachers": {
"0": {
"info": {
"id": "1",
"age": "22",
"driverlicense": "yes"
}
},
"1": {
"info": {
"id": "2",
"age": "51",
"driverlicense": "yes"
}
},
"2": {
"info": {
"id": "1",
"age": "25",
"driverlicense": "no"
}
}
}
};
var yTeachers=[];
$.each(data.teachers, function (i, item) {
if (item.info.age < 25) {
yTeachers[item.info.id] = item.info.age;
}
});

wait $.each is done
No need to wait for $.each to be done just call your variable after.
$.each's callback has 2 arguments, 1st for item index/key and 2nd for item value.
with arrays to check last item called and done use index == array.length -1
$.each(array, function(index, value){
if(index == array.length -1){
console("$.each is done and last item called");
}
});
with objects to check last key called and done use key == Object.keys(obj).pop() and this is your case.
$.each(obj, function(key, value){
if(key == Object.keys(obj).pop()){
console("$.each is done and last item called");
}
});
var data = {
"teachers": {
"0": {
"info": {
"id": "1",
"age": "22",
"driverlicense": "yes"
}
},
"1": {
"info": {
"id": "2",
"age": "51",
"driverlicense": "yes"
}
},
"2": {
"info": {
"id": "1",
"age": "25",
"driverlicense": "no"
}
}
}
}
$.each(data.teachers, function(i, item) {
if (item.info.age < 25) {
alert(item.info.age);
}
if (i == Object.keys(data.teachers).pop()) {
console.log("Done")
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Filtration of multilevel JSON array

I am trying to duplicate value only one time as well as unique from my JSON array.
I have tried the following code.
return_data = {};
return_data.planner = [{
"date": "2019-08-30T12:10:08.000Z",
"event": [{
"name": "Event 1",
"color": "#ccccc"
}]
},
{
"date": "2019-09-30T10:10:08.000Z",
"event": [{
"name": "Event 5",
"color": "#ccccc"
},
{
"name": "Event 4",
"color": "#ccccc"
},
{
"name": "Event 3",
"color": "#ccccc"
}
]
},
{
"date": "2019-09-30T10:10:08.000Z",
"event": [{
"name": "Event 5",
"color": "#ccccc"
},
{
"name": "Event 4",
"color": "#ccccc"
},
{
"name": "Event 3",
"color": "#ccccc"
}
]
},
{
"date": "2019-09-30T10:10:08.000Z",
"event": [{
"name": "Event 5",
"color": "#ccccc"
},
{
"name": "Event 4",
"color": "#ccccc"
},
{
"name": "Event 3",
"color": "#ccccc"
}
]
}
];
res.header('Content-Type', 'application/json');
res.send(JSON.stringify(return_data));
Using above json array:
var u_array = [];
var tem = JSON.parse(JSON.stringify(return_data.response.planner));
for (var i = 0; i < tem.length; i++) {
console.log(tem[i].date);
var status = true;
for (var j = 0; j < u_array.length; j++) {
if (u_array[j].date == tem[i].date) {
status = false;
break;
}
}
if (status) {
u_array.push(tem[i]);
}
};
return_data.response.planner = u_array;
I expect the duplicate value only one time with unique values.
There are many different ways to do what you need. You can follow this thread for some pointers.
Here's one way to get distinct-
/**
* inputArray = Input array
* keySelector = A function to select which key should be used to determine if element is distinct
* keepFirstMatch =
* true - If there is a matching element, and you want to keep the first original item
* false - If there is a matching element and you want to override the original item so that it gets overwritten by latest value in the array
*/
function getDistinct(inputArray, keySelector, keepFirstMatch = false) {
const result = inputArray.reduce((acc, curr) => {
if (keepFirstMatch) {
if (typeof (acc[keySelector(curr)]) === 'undefined') {
acc[keySelector(curr)] = curr;
}
} else {
acc[keySelector(curr)] = curr;
}
return acc;
}, {});
return Object.keys(result).map(k => result[k]);
}
let distinct = getDistinct(planner, (c) => c.date);

Javascript: Splice Multidimensional Object

I'm having this Object/Array Structure :
Obj = {
"User": {
"user1": [{
"desc": "NG60",
"Id": 3473631702,
"Status": "offline"
}],
"user2": [{
"desc": "somevalue",
"Id": 963346121,
"Status": "offline"
},
{
"desc": "othervalue", // SPLICE THIS OUT
"Id": 963346122, // SPLICE THIS OUT
"Status": "offline" // SPLICE THIS OUT
}],
"user3": [{
"desc": "whatever",
"Id": 972878784
}]
}
}
I want to filter out different values, dynamically (fixed in this example)
and if there are no Ids left, I want to delete the whole user Array.
For example, if I want to filter out the 2nd Array Element of user2:
for(var users in Obj) {
for(var Ids in Obj[users]) {
if(Obj[users][Ids].Id == 963346122){
Obj[users][Ids].splice(0, 1); // ERROR HERE
}
}
if(Obj[users][Ids] == undefined) {
delete Obj[users];
}
}
I get this Error:
User[users][Ids].splice(0, 1) is not a function
How to splice only the Array Element that I'm addressing, not the complete user2 Array?
Use array.prototye.filter to remove user from array and use delete to remove the whole user array in case there is no element left:
var obj = {
"User": {
"user1": [
{
"desc": "NG60",
"Id": 3473631702,
"Status": "offline"
}
],
"user2": [
{
"desc": "somevalue",
"Id": 963346121,
"Status": "offline"
},
{
"desc": "othervalue", // SPLICE THIS OUT
"Id": 963346122, // SPLICE THIS OUT
"Status": "offline" // SPLICE THIS OUT
}
],
"user3": [
{
"desc": "whatever",
"Id": 972878784
}
]
}
};
function deleteUser(id) {
Object.keys(obj.User).forEach(user => {
obj.User[user] = obj.User[user].filter(u => u.Id !== id);
if (obj.User[user].length === 0) {
delete obj.User[user];
}
});
}
deleteUser(963346121);
console.log(obj);
deleteUser(972878784);
console.log(obj);
You have to use another for loop to wrap the actual operation because the length is not the same for all iterating objects. That's why you have to slice the object from the proper position.
Try the following:
let Obj = {
"User": {
"user1": [
{
"desc": "NG60",
"Id": 3473631702,
"Status": "offline"
}
],
"user2": [
{
"desc": "somevalue",
"Id": 963346121,
"Status": "offline"
},
{
"desc": "othervalue", // SPLICE THIS OUT
"Id": 963346122, // SPLICE THIS OUT
"Status": "offline" // SPLICE THIS OUT
}
],
"user3": [
{
"desc": "whatever",
"Id": 972878784
}
]
}
}
for(var users in Obj) {
for(var Ids in Obj[users]) {
for(var i=0; i<Obj[users][Ids].length;i++){
if(Obj[users][Ids][i].Id == 963346122){
Obj[users][Ids].splice(i, 1); // ERROR HERE
}
}
}
if(Obj[users][Ids] == undefined) {
delete Obj[users];
}
}
console.log(Obj);
Problem: the splice you used was pointing to string not Object/Array. Use delete rather than splice for Object removal.
Better for future filters:
//using same Obj:
for (i in Obj) {
if (Obj.hasOwnProperty(i)) {
var subObj = Obj[i];
for (j in subObj) {
var child = subObj[j];
for (k in subObj[j]) {
if(child[k].Id == 963346122){ //this user contains specified id the delete this user.
delete child[k];
}
}
}
}
}

creating new object with values of another object in javascript

How can we change the structure of the below data object using JavaScript. Needs to categorize all the names under the std. Thanks in advance
[
{
"name": "Rohan",
"std": "3"
},
{
"name": "Jack",
"std": "2"
},
{
"name": "Peter",
"std": "2"
}
]
to
[
{
"std": "2",
"details": [
{
"name": "Jack"
},
{
"name": "Peter"
}
]
},
{
"std": "3",
"details": [
{
"name": "Rohan"
}
]
}
]
The solution using Array.forEach, Array.map and Object.keys functions:
var arr = [{"name": "Rohan", "std": "3"}, { "name": "Jack", "std": "2" }, { "name": "Peter", "std": "2" }],
grouped = {}, result;
arr.forEach(function(obj){
var std = obj['std'];
if (this[std]) {
this[std]['details'].push({'name' : obj['name']});
} else {
this[std] = {'std' : std, 'details' : [{'name' : obj['name']}]};
}
}, grouped);
result = Object.keys(grouped).map((k) => grouped[k]);
console.log(JSON.stringify(result, 0, 4));
The output:
[
{
"std": "2",
"details": [
{
"name": "Jack"
},
{
"name": "Peter"
}
]
},
{
"std": "3",
"details": [
{
"name": "Rohan"
}
]
}
]
You can use reduce() method here
var data = [{
"name": "Rohan",
"std": "3"
}, {
"name": "Jack",
"std": "2"
}, {
"name": "Peter",
"std": "2"
}],
res = [],
kmap = {};
res = data.reduce(function(a, b) {
// check std value already in array using kmap object
if (kmap[b.std]) {
// if already exist then push name attribute in the details
a[kmap[b.std] - 1].details.push({
'name': b.name
});
} else {
// in else case push the new object
a.push({
'std': b.std,
'details': [{
'name': b.name
}]
});
kmap[b.std] = a.length; // storing the (index + 1) value to avoid 0 in if condition
}
return a;
}, []);
console.log(res);
For older browsers check polyfill option for reduce method.
Problems like this are good candidates for recursion. Here is one possible recursive solution. You can make it much prettier using a functional programming framework such as underscore.js.
var objs = [
{
"name": "Rohan",
"std": "3"
},
{
"name": "Jack",
"std": "2"
},
{
"name": "Peter",
"std": "2"
}
];
function categorize(objs) {
if (objs.length === 0) {
return [];
} else {
var first = objs.shift();
var categorized = categorize(objs);
for(var i = 0; i < categorized.length; i++) {
if (categorized[i].std === first.std) {
categorized[i].details.push({name: first.name});
break;
}
}
if(i === categorized.length) {
categorized.push({std: first.std, details: [{name: first.name}]});
}
return categorized;
}
}
var res = categorize(objs);
console.log(res);
If you're using lodash (I know the question didn't ask this and it's going to be slower, but it may be useful to someone :))
var data = [
{ "name": "Rohan", "std": "3" },
{ "name": "Jack", "std": "2" },
{ "name": "Peter", "std": "2" }
];
var grouped = _.chain(data)
.groupBy('std')
.map(function (people, std) {
return {
std: std,
details: _.map(people, function(person) {
return { name: person.name };
})
}
}).value();

json data retrieve by jquery

How can I get the id of info1 or info2 with each information of the inside loop by jquery loop. Fo example I want to get id 1 from info1 then all the information within id 1 similarly same as from info2. I need the output to show in the browser.
var data = {
"info1": {
"1": {
"clientname": "ruhul yahoo",
"clientemail": "ruhul080#yahoo.com",
"clientusername": "ruhulya"
},
"2": {
"clientname": "kaosar yahoo",
"clientemail": "kaosar080#yahoo.com",
"clientusername": "kaosar"
}
},
"info2": {
"3": {
"id": "24",
"receiver": "5",
"content": "chat system",
"time": "2015-08-19 12:09:19"
},
"4": {
"id": "23",
"receiver": "4",
"content": "chat system",
"time": "2015-08-19 12:09:19"
}
},
}
Thanks in advance.
Iterate the json array and access the object like the following code.
var data = {
"info1": {
"1": {
"clientname": "ruhul yahoo",
"clientemail": "ruhul080#yahoo.com",
"clientusername": "ruhulya"
},
"2": {
"clientname": "kaosar yahoo",
"clientemail": "kaosar080#yahoo.com",
"clientusername": "kaosar"
}
},
"info2": {
"3": {
"id": "24",
"receiver": "5",
"content": "chat system",
"time": "2015-08-19 12:09:19"
},
"4": {
"id": "23",
"receiver": "4",
"content": "chat system",
"time": "2015-08-19 12:09:19"
}
},
};
for(var j in data){
for(var k in data[j]){
console.log(data[j][k]);
}
}
Your browser's Console will log the following objects if you run the above example.
Object {clientname: "ruhul yahoo", clientemail: "ruhul080#yahoo.com", clientusername: "ruhulya"}
Object {clientname: "kaosar yahoo", clientemail: "kaosar080#yahoo.com", clientusername: "kaosar"}
Object {id: "24", receiver: "5", content: "chat system", time: "2015-08-19 12:09:19"}
Object {id: "23", receiver: "4", content: "chat system", time: "2015-08-19 12:09:19"}
Then you can access the values like a normal object console.log(data[j][k].clientname);
This function will find you the first instance of a variable name in the object. If you need to find a variable in a specific path you could amend this function fairly easily to do that. Certainly the function as is passes the test case you've provided.
function findVar(data, varName) {
for (var i in data) {
if (i === varName) return data[i];
if (typeof (data[i]) === 'object') {
var findResult = findVar(data[i], varName)
if (typeof(findResult) !== 'undefined')
{
return findResult;
}
}
}
return undefined;
}
Firstly, This is not a valid JSON, Rmove the last , before last {
Secondly , parse it as a JSON and get the info as
data.info1[1].clientname
var data = JSON.parse('{"info1":{"1":{"clientname":"ruhul yahoo","clientemail":"ruhul080#yahoo.com","clientusername":"ruhulya"},"2":{"clientname":"kaosar yahoo","clientemail":"kaosar080#yahoo.com","clientusername":"kaosar"}},"info2":{"3":{"id":"24","receiver":"5","content":"chat system","time":"2015-08-19 12:09:19"},"4":{"id":"23","receiver":"4","content":"chat system","time":"2015-08-19 12:09:19"}}}');
alert(data.info1[1].clientname);
alert(data.info1[2].clientname);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
You can iterate over this object like this
for(var i in data){
for(var j in data[i]){
console.log(data[i][j]);
}
}

value got overwritten assigning json value within loop

How can I produce something like this?
{
"drink": {
"2": {
"name": "coke",
"type": "drink"
},
"3": {
"name": "coke",
"type": "drink"
}
},
"food": {
"id": "1",
"name": "1 Hour Snooker",
"type": "food"
}
}
I have problem producing multiple object under 'drink' object. It got overwritten with my below code:
http://jsfiddle.net/jLgh4at5/
var json = {
"results": {
"slots": [{
"id": "3",
"name": "pepsi",
"type": "drink"
}, {
"id": "1",
"name": "1 Hour Snooker",
"type": "food"
}, {
"id": "2",
"name": "coke",
"type": "drink"
}]
}
}
var data = {
"slots": {
}
}
json.results.slots.forEach(function (b) {
if (b["type"] == "food") {
data.slots["food"] = b;
} else {
data.slots["drink"] = b;
}
});
console.log(data);
Use array index to resolve the issue.
json.results.slots.forEach(function (b,i) {
if (b["type"] == "food") {
if(data.slots["food"])
data.slots["food"][i] = {"name":b.name,"type":"food"};
else
data.slots["food"] = {};
} else {
if(data.slots["drink"])
data.slots["drink"][i] = {"name":b.name,"type":"drink"};
else
data.slots["drink"] = {};
}
});
Or you can optimize the code as shown below.
var data = {
"slots": {
"food": {},
"drink": {}
}
};
json.results.slots.forEach(function (b,i) {
if (b["type"] == "food") {
data.slots["food"][i] = {"name":b.name,"type":"food"};
} else {
data.slots["drink"][i] = {"name":b.name,"type":"drink"};;
}
});
Here is the updated JSFiddle

Categories

Resources