Find index of an element in javascript array of objects - javascript

I am new to javascript and want to find the index of the given key-value at the bottom but not able to do so. Where am i wrong? The data in the array is copied form a json file which is valid as checked on jsonlint.
var productArray=[
{
"name1":"Electronics",
"id1":{
"products1":{
"id":1.1,
"name":"Microsoft Keyboard",
"description":"good keyboard",
"rating":3,
"price":500,
"freeDeliv":true,
"seller":"MS",
"quanAvl":10
},
"products2":{
"id":1.2,
"name":"ASUS phone",
"description":"good phone",
"rating":4,
"price":10000,
"freeDeliv":true,
"seller":"ASUS",
"quanAvl":10
},
"products3":{
"id":1.3,
"name":"iPhone",
"description":"good phone",
"rating":3,
"price":50000,
"freeDeliv":false,
"seller":"Apple",
"quanAvl":100
}
},
"name2":"Clothing",
"id2":{
"products4":{
"id":2.1,
"name":"Jeans",
"description":"good Jeans",
"rating":3,
"price":800,
"freeDeliv":true,
"seller":"Levis",
"quanAvl":100
},
"products5":{
"id":2.2,
"name":"TShirt",
"description":"good TShirt",
"rating":4,
"price":1000,
"freeDeliv":true,
"seller":"Peter",
"quanAvl":1000
},
"products6":{
"id":2.3,
"name":"Sherwani",
"description":"very good",
"rating":4,
"price":50000,
"freeDeliv":false,
"seller":"Maanyavar",
"quanAvl":1000
}
}},
];
var display=function(productArray,prodKey,value){
for(x in productArray)
{
if(productArray[x][prodKey]==value)
{
console.log(x);
}
else{
alert("Not Found");
}
}
}
display(productArray,"name","Sherwani");

this is the answer. I have tried this
var display=function(productArray_,prodKey,value){
p = productArray_[0]["id2"];
found = false;
for (var key in p) {
if (p.hasOwnProperty(key)) {
p2 = p[key];
for(var key2 in p2){
if(p2.hasOwnProperty(key2)){
if(key2 == prodKey && p2[key2] == value){
console.log(key2); //index of value you looking for
console.log(p2[key2]) //value from index you looking for
alert(key2);
found = true;
}
}
}
}
}
if(!found)
alert("not found");
}
display(productArray,"name","Sherwani");
but I'm agree, this is a very bad object structure. you should change the json structure so you can parse it more easily
UPDATE: you should avoid creating json object wherever possible (begins with "{" and ends with "}"), and instead create json array (begins with "[" and ends with "]").
here is a better structure and how to parse it
var productArray=[
{
"name": "Electronics",
"list": [
{
"code": "products1",
"id": 1.1,
"name": "Microsoft Keyboard",
"description": "good keyboard",
"rating": 3,
"price": 500,
"freeDeliv": true,
"seller": "MS",
"quanAvl": 10
},
{
"code": "products2",
"id": 1.2,
"name": "ASUS phone",
"description": "good phone",
"rating": 4,
"price": 10000,
"freeDeliv": true,
"seller": "ASUS",
"quanAvl": 10
},
{
"code": "products3",
"id": 1.3,
"name": "iPhone",
"description": "good phone",
"rating": 3,
"price": 50000,
"freeDeliv": false,
"seller": "Apple",
"quanAvl": 100
}
]
},
{
"name": "Clothing",
"list": [
{
"code": "products4",
"id": 2.1,
"name": "Jeans",
"description": "good Jeans",
"rating": 3,
"price": 800,
"freeDeliv": true,
"seller": "Levis",
"quanAvl": 100
},
{
"code": "products5",
"id": 2.2,
"name": "TShirt",
"description": "good TShirt",
"rating": 4,
"price": 1000,
"freeDeliv": true,
"seller": "Peter",
"quanAvl": 1000
},
{
"code": "products6",
"id": 2.3,
"name": "Sherwani",
"description": "very good",
"rating": 4,
"price": 50000,
"freeDeliv": false,
"seller": "Maanyavar",
"quanAvl": 1000
}
]
},
]
var display=function(productArray_,prodKey,value){
found = false;
for(var key in productArray_){
for(var key2 in productArray_[key]){
if(key2 == "list"){
for(var key3 in productArray_[key][key2]){
for(var key4 in productArray_[key][key2][key3]){
if(key4 == prodKey
&& productArray_[key][key2][key3][key4] == value
){
console.log(key4);
console.log(productArray_[key][key2][key3][key4]);
alert(key4);
found = true;
}
}
}
}
}
}
if(!found)
alert("not found");
}
display(productArray,"name","Sherwani");

Name you are looking for in your example is one level deeper. This should work:
var display = function(productArray, prodKey, value){
for (x in productArray) {
for (prod in productArray[x]) {
if (productArray[x][prod][prodKey] == value) {
console.log(x);
} else {
alert("Not Found");
}
}
}
}

Related

Find every possibilitie in an array of object comparing key values

I have an specific math formula which receives three parameters and I'm trying to get from an array of object all the possibilities to run this math formula.
It's regards to sports.
Imagine a match where there are 3 possibility: Team A (win) - Team B (win) - Draw.
3 bet websites are dealing with this event. But the 3 of them have different odds values for this match.
I want to run those 3 bet websites to get all posibilities I can have for this event. Never getting more than one odd from the same bet website.
Example:
Website A: team A (win)
Website B: team B (win)
Website C: draw
I'm using JavaScript for that.
Thank you in advance for you time and support.
Really appreciate that.
Here is an example of data I have to get these possibilities.
Each obj is a website and into the object, the odds are on the key "outcomes".
The array of object here has 3 objects, but it can have more
[
{
"key": "betmgm",
"title": "BetMGM",
"last_update": "2022-12-14T04:30:40Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 138
},
{
"name": "Tottenham Hotspur",
"price": 200
},
{
"name": "Draw",
"price": 225
}
]
}
]
},
{
"key": "barstool",
"title": "Barstool Sportsbook",
"last_update": "2022-12-14T04:30:22Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
},
{
"key": "twinspires",
"title": "TwinSpires",
"last_update": "2022-12-14T04:17:45Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
}
]
I would like to receive an array with the possibilities like this:
[
{
"bookMaker": "TwinSpires",
"name": "Tottenham Hotspur",
"price": 230,
},
{
"bookMaker": "Barstool Sportsbook",
"name": "AC Milan",
"price": 130,
},
{
"bookMaker": "BetMGM",
"name": "Draw",
"price": 225,
}
]
The algorithm is quite simple. First, we take all the outcomes of the first Bet website. We shuffle them randomly.
Then we simply loop through the JSON object, which is a list of bet websites, not to mention the fact that both the number of outcomes must be the same as the number of bet websites. We assign for each bet website the next item of the shuffled outcomes. We log it to the console.
Here is the algorithm:
var data = [
{
"key": "betmgm",
"title": "BetMGM",
"last_update": "2022-12-14T04:30:40Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 138
},
{
"name": "Tottenham Hotspur",
"price": 200
},
{
"name": "Draw",
"price": 225
}
]
}
]
},
{
"key": "barstool",
"title": "Barstool Sportsbook",
"last_update": "2022-12-14T04:30:22Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
},
{
"key": "twinspires",
"title": "TwinSpires",
"last_update": "2022-12-14T04:17:45Z",
"markets": [
{
"key": "h2h",
"outcomes": [
{
"name": "AC Milan",
"price": 130
},
{
"name": "Tottenham Hotspur",
"price": 220
},
{
"name": "Draw",
"price": 230
}
]
}
]
}
];
start(data);
function start(data) {
var outcomes = data[0].markets[0].outcomes;
if (data.length != outcomes.length) {
alert("Invalid data!");
return;
}
var results = createResults(data);
printResults(results);
}
function createResults(data) {
var outcomes = data[0].markets[0].outcomes;
var newOutcomesNames = shuffleOutcomes(outcomes);
var results = [];
for (var i = 0; i < data.length; i++) {
var currentBetWebsite = data[i];
var currentResult = {};
var currentOutcomes = currentBetWebsite.markets[0].outcomes;
currentResult.bookMaker = currentBetWebsite.title;
currentResult.name = newOutcomesNames[i];
for (var j = 0; j < newOutcomesNames.length; j++) {
if (newOutcomesNames[i] == currentOutcomes[j].name) {
currentResult.price = currentOutcomes[j].price;
}
}
results.push(currentResult);
}
return results;
}
function printResults(results) {
console.log(results);
}
function shuffleOutcomes(outcomes) {
var parsedOutcomes = parseOutcomesNames(outcomes);
var outcomesLength = parsedOutcomes.length;
var newOutcomes = [];
for (var i = 0; i < outcomesLength; i++) {
var random = Math.floor(Math.random() * (outcomesLength - i));
newOutcomes.push(parsedOutcomes[random]);
parsedOutcomes.splice(random, 1);
}
return newOutcomes;
}
function parseOutcomesNames(outcomes) {
var outcomesNames = outcomes.map(o => o.name);
return outcomesNames;
}
Let me know, if you need any further assistance.

Flatten an object using lodash

I have below this nested object
I need to create an array using this object containing keys. And if keys are object then it should use .dot syntax. and if it is an array then it should give me key.0.keyName. Is it possible to do so?
Output
[
"AllowIPNPayment",
"AllowOnlinePayment",
"MetaData.CreateTime",
"MetaData.LastUpdatedTime",
"CustomField.0.DefinitionId",
"CustomField.0.Name",
"CustomField.0.Type",
...
]
What I have tried is just ugly and does give me expected result. If it is possible with more concise way.
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }
let object = {}
for (let k in invoiceObject) {
if (typeof invoiceObject[k] === "object") {
object[k] = {};
for (let l in invoiceObject[k]) {
object[k][l] = "";
}
} else if (typeof invoiceObject[k] === "array") {
object[k] = [];
for (let l in invoiceObject[k][0]) {
object[k][l] = "";
}
} else {
object[k] = "";
}
}
console.log(object)
You can create a recursive function (getSchema) that checks if a value (val) is an object (arrays included), iterate it with _.flatMap(), and collects the keys until it hits a value which is not an object. It then joins the collected keys and returns the string.
const getSchema = (val, keys = []) =>
_.isObject(val) ? // if it's an object or array
_.flatMap(val, (v, k) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys
:
keys.join('.') // return the joined keys
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }
const result = getSchema(invoiceObject)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Without lodash, the main change is to use Object.entries() to get an array of [key, value] pairs, since Array.flatMap() can't iterate objects:
const getSchema = (val, keys = []) =>
typeof val === 'object' && val !== null ? // if it's an object or array
Object.entries(val) // get [key, value] pairs of object/array
.flatMap(([k, v]) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys
:
keys.join('.') // return the joined keys
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }
const result = getSchema(invoiceObject)
console.log(result)
inspired by the answer given in this post and understanding you just want to get the property-names, not values, you could do it like this. sorry, this uses plain javascript.
function flattenObjectToKeyArray(ob) {
var toReturn = [];
for (var prop in ob) {
if (!ob.hasOwnProperty(prop)) continue;
if ((typeof ob[prop]) == 'object' && ob[prop] !== null) {
var flatObject = flattenObjectToKeyArray(ob[prop]);
for (var idx = 0; idx < flatObject.length; idx++) {
toReturn.push(prop + '.' + flatObject[idx]);
}
} else {
toReturn.push(prop);
}
}
return toReturn;
}
You could solve this with a recursive function. The function below keeps track of the current keys, and joins them as soon as an end point is reached (a non-object or empty object/array).
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 };
function getDotKeys(item, keys = []) {
const isObject = item && typeof item == "object";
if (!isObject) return Array.of(keys.join("."));
const pairs = Array.isArray(item)
? item.map((value, index) => [index, value])
: Object.entries(item);
const isEmpty = !pairs.length;
if (isEmpty) return Array.of(keys.join("."));
const result = [];
for (const [key, value] of pairs) {
const dotKeys = getDotKeys(value, [...keys, key]);
result.push(...dotKeys);
}
return result;
}
console.log(getDotKeys(invoiceObject));
This does produce a different result than what you have in your question, since your solution stops at the second level for objects and third level for arrays. This solution also includes more then only index 0.

remove elements from nested object array

I want to remove object based on conditional check from the JSON object using angularjs/jQuery.
I tried with below code but output is not as expected.
Demo: https://plnkr.co/edit/EWwbETITqn7G79Xypt0g?p=preview
angular.module('ui.bootstrap.demo').controller('DataCtrl', function ($scope) {
$scope.responseData = {
"data": [{
"name": "Machine", "quantity": 20, "snVal": 22,
"machine1": [{ "id": 2009, "machineName": "ASD1", "trackID": "34219", "status": "delivered" },
{ "id": 27893, "machineName": "PX20AA", "trackID": "3422", "status": "avail" }],
"machine2": [{ "id": 1023, "machineName": "XY22", "trackID": "1345", "status": "avail" },
{ "id": 1233, "machineName": "PP3DF", "trackID": "112", "status": "delivered" }
]
}]
}
console.log("R1 :: " + JSON.stringify($scope.responseData));
$scope.newResponse = $.grep($scope.responseData.data, function (element, index) { return element.status == "delivered" }, true);
console.log("R2 after removing elements:: " + JSON.stringify($scope.newResponse));
});
Try this,
let responseData = { "data": [{ "name": "Machine", "quantity": 20, "snVal": 22, "machine1": [{ "id": 2009, "machineName": "ASD1", "trackID": "34219", "status": "delivered" }, { "id": 27893, "machineName": "PX20AA", "trackID": "3422", "status": "avail" }], "machine2": [{ "id": 1023, "machineName": "XY22", "trackID": "1345", "status": "avail" }, { "id": 1233, "machineName": "PP3DF", "trackID": "112", "status": "delivered" }] }] } ;
let newResponse = responseData;
newResponse.data.forEach(function (item) {
for (j in item) {
if (j.includes("machine")) {
//better you check if type is array, using Object.prototype.toString.call(j) === "[object Array]"
item[j] = item[j].reduce(function (acc, machine) {
if (machine.status !== "delivered"){
acc.push(machine);
}
return acc;
}, []);
}
}
})|
console.log(newResponse);
Here we are just iterating through all objects in the data field. Since properties like machine1, machine2 is an array, we iterate through it and filter all machines which are not delivered.
You must note that I have used a for-in loop and array reduce() method here.

Fuzzy search deep array only on certain properties

I have a JSON dataset which could be very large when it returns, with the following structure for each object:
{
"ctr": 57,
"averageECPC": 23,
"cost": 2732.54,
"margin": 66,
"profit": 2495.9,
"property": {
"value": "Izzby",
"uri": "/Terrago/2"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 2573.13,
"compare": 0
},
"children": [{
"ctr": 79,
"averageECPC": 54,
"cost": 3554.78,
"margin": 88,
"profit": 3145.81,
"property": {
"value": "Comvex",
"uri": "/Octocore/4"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 1247.92,
"compare": 0
}
}]
}
Now I want to search all objects in the array and return only objects which include a string of some sort, but I only want to search certain properties.
I basically have another array which contains the keys I want to search, e.g.
const iteratees = ['ctr', 'property.value', 'status.stage']
I have lodash available within the project, but I have no idea where to start.
Any ideas?
You could use filter(), some() and reduce() to do this.
const iteratees = ['ctr', 'property.value', 'status.stage'];
var searchFor = 'lo';
var result = arr.filter(function(o) {
return iteratees.some(function(e) {
var res = e.split('.').reduce(function(a, b) {
if(a) return a[b];
}, o);
if(res) {
if((res).toString().indexOf(searchFor) != -1) return true;
}
})
})
var arr = [{
"ctr": 'lorem',
"averageECPC": 23,
"cost": 2732.54,
"margin": 66,
"profit": 2495.9,
"property": {
"value": "Izzby",
"uri": "/Terrago/2"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 2573.13,
"compare": 0
},
"children": [{
"ctr": 79,
"averageECPC": 54,
"cost": 3554.78,
"margin": 88,
"profit": 3145.81,
"property": {
"value": "Comvex",
"uri": "/Octocore/4"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 1247.92,
"compare": 0
}
}]
}, {
name: 'lorem',
ctr: 12,
property: {
value: 1
},
status: {
stage: 1
}
}, {
name: 'ipsum'
}]
const iteratees = ['ctr', 'property.value', 'status.stage'];
var searchFor = 'lo';
var result = arr.filter(function(o) {
return iteratees.some(function(e) {
var res = e.split('.').reduce(function(a, b) {
if (a) return a[b];
}, o);
if (res) {
if ((res).toString().indexOf(searchFor) != -1) return true;
}
})
})
console.log(result)

take JSON input and store it in to an array (javascript)

I have a JSON input of
{
"Categories": {
"Facets": [{
"count": 1,
"entity": "Company",
"Company": [{
"entity": "Ford Motor Co",
"Ford_Motor_Co": [{
"count": 1,
"entity": "Ford"
}]
}]
}, {
"count": 4,
"entity": "Country",
"Country": [{
"entity": "Germany",
"Germany": [{
"count": 1,
"entity": "Germany"
}],
"currency": "Euro (EUR)"
}, {
"entity": "Italy",
"Italy": [{
"count": 1,
"entity": "Italy"
}],
"currency": "Euro (EUR)"
}, {
"entity": "Japan",
"Japan": [{
"count": 1,
"entity": "Japan"
}],
"currency": "Yen (JPY)"
}, {
"entity": "South Korea",
"South_Korea": [{
"count": 1,
"entity": "South Korea"
}],
"currency": "Won (KRW)"
}]
}, {
"count": 5,
"entity": "Persons",
"Persons": [{
"count": 2,
"entity": "Dodge"
}, {
"count": 1,
"entity": "Dodge Avenger"
}, {
"count": 1,
"entity": "Major League"
}, {
"count": 1,
"entity": "Sterling Heights"
}]
}]
}
}
I need to get the values for entity in each level in to an array..
[Company, Ford Motor Co, Ford, ....... , Sterling Heights]
I am able to get thru the first level with the code
for (var k in h.Categories.Facets)
{
alert(h.Categories.Facets[k].entity);
}
How do I reach thru the innerlevels to get the values of entity??
You should do a foreach on each entity. If you know how many levels there are you can nest loops. If not - probably should go for a recursive function.
Edit
Recursive function:
function getEntities(ent)
{
alert(ent);
for (var l in ent)
{
getEntities(ent[l].entity);
}
}
Then use:
for (var k in h.Categories.Facets)
{
getEntities(h.Categories.Facets[k]);
}
Good luck!
The most general recursive answer:
function getEntities(any) {
var entities = [];
if ('entity' in any​) {
entities.push(any.entity);
}
for (var prop in any) {
if (any[prop] instanceof Object && any.hasOwnProperty(prop)) {
entities.append(getEntities(any[prop]));
}
}
return entities;
}
console.log(getEntities(h));
The line:
if (any[prop] instanceof Object && any.hasOwnProperty(prop)) {
Keeps numbers/nulls from bombing and the any.hasOwnProperty(prop) makes up for frameworks that like to attach to the Object prototype.
One way is to write a recursive method that accepts an array and extracts the methods from it.
As suggested, you can use a recursive function to loop through every possible nested combo:
var allEntities = [];
function getEntities(obj)
{
if (obj != null)
{
var entityName = obj["entity"];
alert(entityName);
if (entityName != null)
{
allEntities.push(entityName);
var adjName = entityName.replace(/ /gi, "_");
var entities = obj[adjName];
if (entities != null)
{
for (var e in entities)
{
var innerEntities = getEntities(entities[e]);
for (var inner in innerEntities)
allEntities.push(innerEntities[inner]);
}
}
}
}
}
for (var k in h.Categories.Facets)
{
alert(h.Categories.Facets[k].entity);
getEntities(h.Categories.Facets[k]);
}
alert(allEntities.length);

Categories

Resources