How to iterate through this object? - javascript

I want to iterate through this object by creating a function country(state,foods)
if the state and foods exists in the object,it should return me the state name and foods array of that state.First i tried iterating only state by passing argument state in the function using for in still i didn't get the state name and i don't know what should i do to get foods array.
var india = [
{
"state": "karnataka",
"capital": "Bengaluru",
"foods": ["Mysore masala", "Uthhappa", "Bisi Bele Bhaat"]
},
{
"state": "Maharashtra",
"capital": "Mumbai",
"foods": ["vada pav", "puranpoli", "Missal pav"]
},
{
"state": "Tamil nadu",
"capital": "Chennai",
"foods": ["Medu vada", "aapam", "idli sambhar"]
},
{
"state": "Rajasthan",
"capital": "Jaipur",
"foods": ["Ras malai", "Kadka", "Gujia"]
}
];

This is a poor data structure for your use case, so if you expect to need to search this data often, you might consider having state names as properties on an object for O(1) lookup rather than O(n) approach of iterating this array. That being said, this existing structure can be searched in this case using Array.find().
var result = india.find( item => (item.state === this) , searchState);
console.log(result.foods);

for (var i in india)
{
alert(india[i].state);
// do something else with india[i]
}
Or since india is an array:
for (var i = 0; i < india.length; ++i)
{
// same thing
}
When searching if a specific number or string exists in an array you can use Array.indexOf(), example:
if (india[i].foods.indexOf('Kadka') >= 0)
{
alert(india[i].state + " has food Kadka");
}
A function StateHasFood(state, food) could be something like that:
function StateHasFood(state, food)
{
for (var i in india)
if (india[i].state == state)
return india[i].foods.indexOf(food) >= 0;
return false;
}
Of course you can also return the object relative to the state containing its properties, including it's name and full list of foods like you seem to want:
function StateHasFood(state, food)
{
for (var i in india)
if (india[i].state == state)
if (india[i].foods.indexOf(food) >= 0)
return india[i];
return false;
}

Since you just told me to write a function to check if state and capital are present, and that is true then return the capital. I have wrote this for you. Hope it helps :)
var india = [
{
"state": "karnataka",
"capital": "Bengaluru",
"foods": ["Mysore masala", "Uthhappa", "Bisi Bele Bhaat"]
},
{
"state": "Maharashtra",
"capital": "Mumbai",
"foods": ["vada pav", "puranpoli", "Missal pav"]
},
{
"state": "Tamil nadu",
"capital": "Chennai",
"foods": ["Medu vada", "aapam", "idli sambhar"]
},
{
"state": "Rajasthan",
"capital": "Jaipur",
"foods": ["Ras malai", "Kadka", "Gujia"]
}
];
function country(someState , someCapital){
for (var i in india)
{
if(india[i].state === someState && india[i].capital === someCapital){
return india[i].capital;
}
}
}
document.write(country("Tamil nadu", "Chennai"));

From what you've added in the comments, it seems what you really want is a function getPropForState(state, prop) that will return the value of the specified property associated with the specified state. That is, getPropForState("Rajasthan", "foods") would return an array of foods, and getPropForState("Rajasthan", "capital") would return "Jaipur".
Assuming that is the case, perhaps something like the following:
// same array as in question, but with line breaks removed
// so that it doesn't clutter up my answer
var india = [{"state":"karnataka","capital":"Bengaluru","foods":["Mysore masala","Uthhappa","Bisi Bele Bhaat"]},{"state":"Maharashtra","capital":"Mumbai","foods":["vada pav","puranpoli","Missal pav"]},{"state":"Tamil nadu","capital":"Chennai","foods":["Medu vada","aapam","idli sambhar"]},{"state":"Rajasthan","capital":"Jaipur","foods":["Ras malai","Kadka","Gujia"]}];
function getPropForState(state, prop) {
var item = india.find(v => v.state === state);
if (item)
return item[prop];
}
console.log(getPropForState("Rajasthan", "foods")); // returns ["Ras malai","Kadka","Gujia"]
console.log(getPropForState("Rajasthan", "capital")); // returns "Jaipur"
console.log(getPropForState("Maharashtra", "capital")); // returns "Mumbai"
console.log(getPropForState("Maharashtra", "missing")); // returns undefined
console.log(getPropForState("Queensland", "foods")); // returns undefined
Note that if either the state or the specified other property do not exist then the function will return undefined.

Try forEach() method to iterate and Object.keys to get the key:value pairs. Don't completely understand OP's objective so I'll add objArrKey(). This function takes the array and a specific key and return all values associated with said key.
SNIPPET
var India = [{
"state": "karnataka",
"capital": "Bengaluru",
"foods": [
"Mysoremasala",
"Uthhappa",
"BisiBeleBhaat"
]
}, {
"state": "Maharashtra",
"capital": "Mumbai",
"foods": [
"vadapav",
"puranpoli",
"Missalpav"
]
}, {
"state": "Tamilnadu",
"capital": "Chennai",
"foods": [
"Meduvada",
"aapam",
"idlisambhar"
]
}, {
"state": "Rajasthan",
"capital": "Jaipur",
"foods": [
"Rasmalai",
"Kadka",
"Gujia"
]
}]
India.forEach(function(item) {
Object.keys(item).forEach(function(key) {
console.log("key:" + key + " value:" + item[key]);
});
});
function objArrKey(arr, key) {
return arr.map(function(item) {
return item[key] || null;
});
}
console.log(objArrKey(India, ['state']));
console.log(objArrKey(India, ['capital']));
console.log(objArrKey(India, ['foods']));

Related

Loop through array of nested objects to check empty string es6

I have an array of nested objects:
const array =[
{
"id": 1,
"time": {
"timezone": "2021-09-22T05:36:22.484Z"
"city": "Perth"
"country:: "Australia
"date": "2021/10/10"
}
},
{
​"id": 2,
​"time": {
"timezone": ​"2021-10-22T03:25:26.484Z"
"city": ""
"country: "Americas"
"date": "2021/10/10"
}
},
{
​"id": 3,
​"time": {
"timezone": ​"2021-09-27T02:43:26.564Z"
"city": ""
"country: ""
"date": "2021/10/10"
}
}];
I want to check each value in the time object to see if there exists an empty string without having to have multiple || statements.
What I have tried using lodash:
if(array.find((k)=> _.isEmpty(k.timezone)) || array.find((k)=> _.isEmpty(k.city)) || array.find((k)=> _.isEmpty(k.country)) || array.find((k)=> _.isEmpty(k.date))) {
//do something
} else {
//do something else
}
This seems to do the trick but trying to find a succinct and cleaner way to do this as there could be more values in the time object, preferably in es6.
Check if .some of the Object.values of any of the time subobjects includes the empty string.
if (array.some(
k => Object.values(k.time).includes('')
)) {
// do something
} else {
// do something else
}

Return Javascript child array based on parent filter

Disclaimer: I know some Java but almost nothing about Javascript and have about 2 days to fix someone else's issues, of which this is one small part.
I have a nested array. I know the shop number, but need to get an array of only the parts in that shop.
"shops": [
{
"shopID": "15231",
"city": "Anytown",
"state": "MO",
"inventory": [
{
"description": "filter",
"partnumber": "MGL57047",
"shelf": "Z",
},
{
"description": "filter",
"partnumber": "84060",
"shelf": "A",
}
},
{
"shopID": "15232",
"city": "Springfield",
"state": "IL",
"inventory": [
{
"description": "filter",
"partnumber": "MGL57048",
"shelf": "B",
},
{
"description": "filter",
"partnumber": "84061",
"shelf": "A",
}
}
Here's what I tried:
const enteredShopID = '15231' // This isn't hard-coded in my app.
// Pull the list of all consumables for the current shop
var currentShop = application.data.shops.filter(s => s.shopID == enteredShopID)
This gets me an array with the shop and all of the inventory for that shop, but I need an array of the inventory. I tried
var currentShop = application.data.shops.inventory.filter(s => s.shopID == enteredShopID)
but that didn't work. Really, I'm just fumbling here. Is there a way to make the latter statement work, and somehow refer to the shopID of the parent?
Just use map() after the filter.
var currentShop = application.data.shops
.filter(s => s.shopID == enteredShopID)[0]
// checking if the current shop is actually null because no shops matched the ID
var currentShopInventory = (currentShop || {}).inventory || []
or use find()
// Note: If you use find(), there's a chance that there is no matching object
// So you'll have to check for that before you access the "inventory" key
// Otherwise you'll get "Cannot access 'inventory' of null"
var matchingShop = application.data.shops
.find(s => s.shopID == enteredShopID)
// Doing the checking here using an "or" if the matchingShop is null
var currentShop = matchingShop || {}
var currentShopInventory = currentShop.inventory || []

Delete list of objects based from an array ids using ES6

I have an arrays with ids and object lists with same ids contained in arrays, how can I remove objects based from array ids?
array:
user_ids: [“id001”, “id004”]
object list:
{
{
“user_id”: “id001”,
“city”: “Seattle”
},
{
“user_id”: “id002”,
“city”: “Los Angeles”
},
{
“user_id”: “id003”,
“city”: “San Francisco”
},
{
“user_id”: “id004”,
“city”: “San Diego”
}
}
so the result would be:
{
{
“user_id”: “id002”,
“city”: “Los Angeles”
},
{
“user_id”: “id003”,
“city”: “San Francisco”
}
}
Array methods
Array.prototype.filter()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Array.prototype.includes()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
The includes() method determines whether an array includes a certain element, returning true or false as appropriate.
let user_ids = ["id001", "id004"];
let list = [
{
"user_id": "id001",
"city": "Seattle"
},
{
"user_id": "id002",
"city": "Los Angeles"
},
{
"user_id": "id003",
"city": "San Francisco"
},
{
"user_id": "id004",
"city": "San Diego"
}
];
console.log(list.filter( o => !(user_ids.includes(o.user_id)) ));
If the list of objects is an array, you could do it like so:
for (var i = 0;i<object_list.length;i++){
if (object_list[i]["user_id"] in user_ids){
object_list.splice(i, 1);
}
}
If it is an object, it could be done this way:
for (var i in object_list){
if (object_list[i]["user_id"] in user_ids){
delete object_list[i];
}
}

JavaScript Remove Object From Array Based on Child Property

Using vanilla JavaScript (supported by the latest version of Chrome, don't worry about IE) and/or lodash/underscore but no jQuery how can I take this array:
[
{
"id": 1,
"places": {
"city": "boston"
}
},
{
"id": 2,
"places": {
"city": "new york"
}
}
]
...and remove the entire object that has a city of "boston":
[
{
"id": 2,
"places": {
"city": "new york"
}
}
]
Please keep in mind this array could have dozens of entries. Thank you!
http://plnkr.co/edit/JW3zd6A7OcmihM4CTh1D?p=preview
One of the ways you can do this is by using filter. For example:
var dataWithoutBoston = data.filter(function (el) {
return el.places.city !== "boston";
});
And to make it reusable, you can have a function like this:
function removeFromCity(data, name) {
var result = data.filter(function (el) {
return el.places.city !== name;
});
return result;
};

Push Json filtered key values to nested ul with Javascript

I need help pushing the values from a filtered json, I need this generate a nested ul list, I can not modify the json format at this point, I you check the console.log you will see the values to create the list, at this point I can't figure how to complete the 'for loop' to render the html markup needed, any help will be appreciated, this is the jsfiddle http://jsfiddle.net/43jh9hzz/, and if you check the console log you will see the values.
This is the Js:
var json='';
var property_set = new Set();
function iterate(obj, stack) {
json="<ul>";
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
}
else {
// console.log(property);
property_set.add(property);
json+="<li>";
if(typeof obj[property] !== "number") {
json+="<li>"+obj[property]+"</li>";
console.log(obj[property]);
}
}
} json += "</li>";
}
}
var listEl = document.getElementById('output');
iterate(jsonObj)
And this is the json format:
var jsonObj =
{
"level_1": [
{
"level_1_name": "CiscoSingaporeEBC",
"level_2": [
{
"level_2_name": "Khoo Tech Puat",
"level_2_id": 2222,
"level_3": [
{
"name": "Boon Leong Ong",
"id": 6919
},
{
"name": "Kiat Ho",
"id": 6917
},
{
"name": "Overall Experience",
"id": 6918
}
]
}
]
},
{
"level_1_name": "CiscoLondonEBC",
"level_2": [
{
"level_2_name": "Bernard Mathews Ltd.",
"level_2_id": 2367,
"level_3": [
{
"name": "Barry Pascolutti",
"id": 7193
},
{
"name": "Kathrine Eilersten",
"id": 7194
},
{
"name": "Martin Rowley",
"id": 7189
}
]
},
{
"level_2_name": "FNHW Day 1",
"level_2_id": 5678,
"level_3": [
{
"name": "Jurgen Gosch",
"id": 7834
},
{
"name": "Overall Experience",
"id": 7835
}
]
},
{
"level_2_name": "Groupe Steria Day 1",
"level_2_id": 2789,
"level_3": [
{
"name": "Adam Philpott",
"id": 7919
},
{
"name": "Pranav Kumar",
"id": 7921
},
{
"name": "Steve Simlo",
"id": 7928
}
]
}
]
}
]
};
enter code here
I'm not sure if I am interpretting your request correctly, but I think this is what you want: http://jsfiddle.net/mooreinteractive/43jh9hzz/1/
Basically, you are calling the iterate function to run, but then that's it. The function actually needs to also return the value it generates.
I've added to the end of the function, after the for loop completes:
return json;
Do now the function returns the value it generated, but there are some other issues too. When you recursively call the iterate function again inside the iterate function, you actually want to add what it returns to the current json string housing all of your returned value.
So on that line I changed it from:
iterate(obj[property], stack + '.' + property);
to
json += iterate(obj[property], stack + '.' + property);
Now that other value will come back as well inside the main list you were creating in the first run of the function. Ok so that's pretty close, but one more small thing. I think when you added additional surrounding LI, you actually wanted to do an UL. I changed those to ULs and now I think the result is like a UL/LI list representing the text parts of the JSON object.
Again, that may not be exactly what you were after, but I think the main take away is using the function to return the value, not just generate it, then do nothing with it.

Categories