Populating select options using jquery fails - javascript

I was trying to populate select options from a JSON using jquery. Here is my html form code (with search options) -
<div class="form-group row">
<label for="" class="col-sm-2 form-control-label">Country</label>
<div class="col-sm-10">
<select class="form-control selectpicker" id="country" placeholder="" data-live-search="true">
</select>
</div>
</div>
And here is the code i have write to populate the form with documents and also catch and echo the selection -
(function() {
var url = "dummy.json";
countries = [];
divisions = [];
districts = [];
subdistricts = [];
$.getJSON(url)
.done(function( data ) {
countries.push(data['Country']);
divisions.push(data['Divisions']);
districts.push(data['Districts']);
subdistricts.push(data['Subdistricts']);
$('#country').empty();
for(i=0; i<countries[0].length; i++){
$('#country').append('<option data-tokens="' + countries[0][i]["name"] +'" value="' + i + '">' + countries[0][i]["name"] + '</option>');
};
$('#country').change(function(){
var selected = $( this ).val();
console.log(selected);
});
});
})();
My problem is- the selection form is not populating after running the code. Is there any syntax error in my code ? Or am i approaching it in wrong way ? If anyone want to see the json file, i will post it here.
Here is my JSON file -
{
"Country": [
{
"id": "01",
"name": "China",
"capital": "Beijing",
"divisions": "[01, 02, 03]",
"districts": "[01, 02, 03]"
},
{
"id": "02",
"name": "Bangladesh",
"capital": "Dhaka",
"divisions": "[04,05,06,07,08,09,10,11]",
"Districts": "[04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]"
},
{
"id": "03",
"name": "Singapore",
"Capital": "Singapore City",
"Divisions": "[12,13,14,15,16]",
"Districts": "[32,33,34,35,36]"
}
],
"Divisions": [
{
"id": "01",
"name": "Shengdong",
"districts": [
[
"[01]"
]
]
},
{
"id": "02",
"name": "Anhui",
"districts": [
[
"[02]"
]
]
},
{
"id": "03",
"name": "Fujian",
"districts": [
[
"[03]"
]
]
},
{
"id": "04",
"name": "Barisal",
"districts": "[4,5,6]"
},
{
"id": "05",
"name": "Chittagong",
"Districts": "[07,08,09,10]"
},
{
"id": "06",
"name": "Dhaka",
"Districts": "[11,12]"
},
{
"id": "07",
"name": "Khulna",
"Districts": "[13,14]"
},
{
"id": "08",
"name": "Central Region",
"Districts": [
[
"[15]"
]
]
},
{
"id": "09",
"name": "North Region",
"Districts": [
[
"[16]"
]
]
},
{
"id": "10",
"name": "East Region",
"Districts": [
[
"[17]"
]
]
},
{
"id": "11",
"name": "North-east Region",
"Districts": [
[
"[18]"
]
]
},
{
"id": "12",
"name": "West Region",
"Districts": [
[
"[19]"
]
]
}
],
"Districts": [
{
"id": "1",
"name": "Dongcheng",
"Subdistricts": [
[
"[1]"
]
]
},
{
"id": "2",
"name": "Yaohai",
"Subdistricts": [
[
"[2]"
]
]
},
{
"id": "3",
"name": "Luyang",
"Subdistricts": [
[
"[3]"
]
]
},
{
"id": "4",
"name": "Barisal",
"Subdistricts": [
[
"[4]"
]
]
},
{
"id": "5",
"name": "Barguna",
"Subdistricts": [
[
"[5]"
]
]
},
{
"id": "6",
"name": "Bhola",
"Subdistricts": "[6,7]"
},
{
"id": "7",
"name": "Chittagong",
"Subdistricts": "[8,9,10,11]"
},
{
"id": "8",
"name": "Cox's Bazar",
"Subdistricts": [
[
"[12]"
]
]
},
{
"id": "9",
"name": "Comilla",
"Subdistricts": [
[
"[13]"
]
]
},
{
"id": "10",
"name": "Feni",
"Subdistricts": [
[
"[14]"
]
]
},
{
"id": "11",
"name": "Dhaka",
"Subdistricts": [
[
"[15]"
]
]
},
{
"id": "12",
"name": "Narayanganj",
"Subdistricts": [
[
"[16]"
]
]
},
{
"id": "13",
"name": "Khulna",
"Subdistricts": [
[
"[17]"
]
]
},
{
"id": "14",
"name": "Bagerhat",
"Subdistricts": [
[
"[18]"
]
]
},
{
"id": "15",
"name": "Radin Mas SMC",
"Subdistricts": [
[
"[19]"
]
]
},
{
"id": "16",
"name": "Jalan Besar GRC",
"Subdistricts": [
[
"[20]"
]
]
},
{
"id": "17",
"name": "Mount Batten GRC",
"Subdistricts": [
[
"[21]"
]
]
},
{
"id": "18",
"name": "Marine Parade GRC",
"Subdistricts": [
[
"[22]"
]
]
},
{
"id": "19",
"name": "West Coast GRC",
"Subdistricts": [
[
"[23]"
]
]
}
],
"Subdistricts": [
{
"id": "1",
"name": "Dailang",
"postcodes": "[736200,404000,100000]"
},
{
"id": "2",
"name": "Changchung",
"postcodes": "[864000,504100,905050]"
},
{
"id": "3",
"name": "Chengdu",
"postcodes": "[994000,909100,109050]"
},
{
"id": "4",
"name": "Agailjhara",
"postcodes": "[8240,8241,8242]"
},
{
"id": "5",
"name": "Amtali Upazella",
"postcodes": "[9940,9941,8878]"
},
{
"id": "6",
"name": "Bhola Sadar",
"postcodes": "[7230,7741,7752]"
},
{
"id": "7",
"name": "Daulatkhan",
"postcodes": "[8650,8871,8880]"
},
{
"id": "8",
"name": "Sitakund",
"postcodes": "[4320,4321,4325]"
},
{
"id": "9",
"name": "Satkania",
"postcodes": "[4460,4461,4458]"
},
{
"id": "10",
"name": "Port",
"postcodes": "[4530,4555,4532]"
},
{
"id": "11",
"name": "Dabal Muring",
"postcodes": "[4320,4321,4448]"
},
{
"id": "12",
"name": "Chokaria",
"postcodes": "[5320,5321,5432]"
},
{
"id": "13",
"name": "Daudkandi",
"postcodes": "[6432,6433,6555]"
},
{
"id": "14",
"name": "Feni sadar",
"postcodes": "[3240,3241,3378]"
},
{
"id": "15",
"name": "Dhanmondi",
"postcodes": "[2330,2441,2878]"
},
{
"id": "16",
"name": "Narayanganj Sadar",
"postcodes": "[6444,6543,6657]"
},
{
"id": "17",
"name": "Batiaghat",
"postcodes": "[7780,7781,7778]"
},
{
"id": "18",
"name": "Bagerhat Sadar",
"postcodes": "[7450,7451,7458]"
},
{
"id": "19",
"name": "Changi",
"postcodes": "[736200,404000,555776]"
},
{
"id": "20",
"name": "Quenstown",
"postcodes": "[787899,878788,987789]"
},
{
"id": "21",
"name": "Clementi",
"postcodes": "[989778,976543,975432]"
},
{
"id": "22",
"name": "Tuas",
"postcodes": "[109901,110900,121345]"
},
{
"id": "23",
"name": "East Region",
"postcodes": "[609098,567654,765432]"
}
]
}
Latest EDIT:
I have checked in the console. HTML form with options value is loading perfectly, but for some reason my form is not showing options. Here is my latest code -
for(var i=0; i<countries[0].length; i++){
$('#country').append('<option data-tokens="' + countries[0][i]["name"].toLowerCase() +'" value="' + countries[0][i]["id"] + '">' + countries[0][i]["name"] + '</option>');
};
HTML code after loading in the console -
<select id="country" class="form-control selectpicker" data-live-search="true" placeholder="" tabindex="-98">
<option value="01" data-tokens="china">China</option>
<option value="02" data-tokens="bangladesh">Bangladesh</option>
<option value="03" data-tokens="singapore">Singapore</option>
</select>
Any reason for such phenomenon ?

Change the loop for :
for(var i=0; i<countries[0].length; i++){
$('#country').append('<option data-tokens=' + countries[0][i].name +'value=' + i + '>' + countries[0][i].name + '</option>');
};

Well, it seems my problem was occurring for the selectpicker class i have used. The plugin i have used to generate the search options for the selection has its own criteria for populating options in a select form. Here is the link of their documentation - https://silviomoreto.github.io/bootstrap-select/methods/#selectpickerrefresh
Here is my revised JS code -
(function() {
var url = "dummy.json",
countries = [],
divisions = [],
districts = [],
subdistricts = [],
$.getJSON(url)
.done(function( data ) {
countries.push(data['Country']);
divisions.push(data['Divisions']);
districts.push(data['Districts']);
subdistricts.push(data['Subdistricts']);
var option_string = '';
for(var i=0; i<countries[0].length; i++){
option_string += '<option data-tokens="' + countries[0][i]["name"].toLowerCase() +'" value="' + countries[0][i]["id"] + '">' + countries[0][i]["name"] + '</option>';
}
$('#country').empty().append(option_string).change(function(){
var selected = $(this).val();
console.log(selected);
}).selectpicker('refresh');
});
})();

Related

Extract the parent node name from Tree who has childrens

I want to iterate the tree and need to get the id of all the nodes which has the children in string array. while looping it is just returning me the record but doesn't extract the name of the node.
e.g const result = ['root', 'USER', 'ROLE', 'DASHBOARD', 'BRAND', 'COMPANY'];
{
"id": "root",
"name": "Roles and Permissions",
"children": [
{
"id": "USER",
"name": "USER",
"children": [
{
"id": "1",
"name": "VIEW"
},
{
"id": "2",
"name": "CREATE"
},
{
"id": "3",
"name": "EDIT"
}
]
},
{
"id": "ROLE",
"name": "ROLE",
"children": [
{
"id": "8",
"name": "VIEW"
},
{
"id": "9",
"name": "CREATE"
},
{
"id": "10",
"name": "EDIT"
},
{
"id": "11",
"name": "DELETE"
}
]
},
{
"id": "DASHBOARD",
"name": "DASHBOARD",
"children": [
{
"id": "BRAND",
"name": "BRAND",
"children": [
{
"id": "52",
"name": "VIEW"
},
{
"id": "53",
"name": "CREATE"
},
{
"id": "54",
"name": "EDIT"
},
{
"id": "55",
"name": "DELETE"
}
]
},
{
"id": "COMPANY",
"name": "COMPANY",
"children": [
{
"id": "56",
"name": "VIEW"
},
{
"id": "57",
"name": "CREATE"
},
{
"id": "58",
"name": "EDIT"
},
{
"id": "59",
"name": "DELETE"
}
]
}
]
}
]
}
I tried various looping method to get the list, e.g. but not returning the exact name of the node.
function getParent(nodes) {
if(Array.isArray(nodes.children)) {
return nodes.children.map((node) => getParent(node));
}
return nodes.name;
}
You can store the resp in an array and return that array.
const q = {
"id": "root",
"name": "Roles and Permissions",
"children": [
{
"id": "USER",
"name": "USER",
"children": [
{
"id": "1",
"name": "VIEW"
},
{
"id": "2",
"name": "CREATE"
},
{
"id": "3",
"name": "EDIT"
}
]
},
{
"id": "ROLE",
"name": "ROLE",
"children": [
{
"id": "8",
"name": "VIEW"
},
{
"id": "9",
"name": "CREATE"
},
{
"id": "10",
"name": "EDIT"
},
{
"id": "11",
"name": "DELETE"
}
]
},
{
"id": "DASHBOARD",
"name": "DASHBOARD",
"children": [
{
"id": "BRAND",
"name": "BRAND",
"children": [
{
"id": "52",
"name": "VIEW"
},
{
"id": "53",
"name": "CREATE"
},
{
"id": "54",
"name": "EDIT"
},
{
"id": "55",
"name": "DELETE"
}
]
},
{
"id": "COMPANY",
"name": "COMPANY",
"children": [
{
"id": "56",
"name": "VIEW"
},
{
"id": "57",
"name": "CREATE"
},
{
"id": "58",
"name": "EDIT"
},
{
"id": "59",
"name": "DELETE"
}
]
}
]
}
]
}
let result = []
function r(nodes){
if(Array.isArray(nodes.children)){
result.push(nodes.name);
nodes.children.map((c) => r(c))
return result;
}
return result;
}
console.log(r(q))
You can simply use a recursive function. Here ids is an array. You can initialize it before calling the function. Call this function in your getting IDs method.
const getIdFromNodesWithChild = (node) => {
if (node.children != undefined){
ids.push(node.id)
const children_list = node.children
children_list.forEach( new_child => getIdFromNodesWithChild(new_child))
}}
caller function
const returnIds = (tree) => {
ids = []
getIdFromNodesWithChild(tree)
return (ids)
}
result : ['root', 'USER', 'ROLE', 'DASHBOARD', 'BRAND', 'COMPANY']

Get difference between two nested arrays in javascript

I wanted to get the difference between two arrays which is nested.
let firstArray = {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "4.0",
"count": [
{
"id": "21",
"countName": "ABC",
"countThreshold": "7.0"
},
{
"id": "22",
"workscopeName": "DEF",
"countThreshold": "4242"
}
]
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "2.0"
},
{
"id": "6",
"countName": "DEF",
"countThreshold": "3.0"
}
]
}
]
}
let changedArray= {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "5",
"count": [
{
"id": "21",
"countName": "ABC",
"countThreshold": "7.0"
},
{
"id": "22",
"workscopeName": "DEF",
"countThreshold": "4242"
}
]
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "60"
},
{
"id": "6",
"countName": "DEF",
"countThreshold": "3.0"
}
]
}
]
}
Expected result:
let finalArray = {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "5",
"count": []
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "60"
}
]
}
]
}
I would like to track the diffference based on the value property inside 'levelData' array and countThreshold inside count array.
i tried repeating two arrays in for loop but was not able to repeat Any simultaneously as its nested.Do let me know any quick approach..
Thanks
Try using map to iterate for each levelData finding their respective in firstArray by name then filter by matching its properties:
let firstArray={"family":"BLUE","globalThreshold":"2.0","levelData":[{"name":"India","value":"4.0","count":[{"id":"21","countName":"ABC","countThreshold":"7.0"},{"id":"22","workscopeName":"DEF","countThreshold":"4242"}]},{"name":"FEDERAL EXPRESS CORPORATION","value":"1.0","count":[{"id":"5","countName":"ABC","countThreshold":"2.0"},{"id":"6","countName":"DEF","countThreshold":"3.0"}]}]};
let changedArray={"family":"BLUE","globalThreshold":"2.0","levelData":[{"name":"India","value":"5","count":[{"id":"21","countName":"ABC","countThreshold":"7.0"},{"id":"22","workscopeName":"DEF","countThreshold":"4242"}]},{"name":"FEDERAL EXPRESS CORPORATION","value":"1.0","count":[{"id":"5","countName":"ABC","countThreshold":"60"},{"id":"6","countName":"DEF","countThreshold":"3.0"}]}]}
var arr = changedArray.levelData.map(ele => {
var count = firstArray.levelData.find(x => x.name == ele.name).count;
ele.count = ele.count.filter(x => !count.some(y => x.id == y.id && x.countThreshold == y.countThreshold));
return ele;
})
console.log(arr);

Remove an associate object while looping through using map

I have a json array and i need to delete the subarray whose id value is 5, which is falling under the serialNo 1. I tried the following method, but its not deleting any entry in the subarray.
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details.map((data) => {
if (data.serialNo === "1") {
data.subArray.map((subDetails) => {
if (subDetails.id === "5") {
delete data.subArray[subDetails];
}
})
}
})
I don't know why you explicitely wants to use the map function. But the following works:
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details = Details.map(function (data) {
if (data.serialNo === "1") {
data.subArray = data.subArray.filter(function (sa) {
return (sa.id !== "5");
});
}
return data;
});
console.log(Details);
The first problem is that you're not returning anything from the map functions. The second problem is that data.subArray[subDetails] is undefined, subDetails is an object not an index in the data.subArray array. You can use a combination of map and filter to accomplished this instead of using delete.
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details.map((data) => {
if (data.serialNo === "1") {
data.subArray = data.subArray.filter((subDetails) => {
return subDetails.id !== "5";
})
}
return data;
});
console.log(Details);
If you want to stick with map what you need to do is to return undefined when subDetails.id is 5.
let Details = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
Details.map((data) => {
if (data.serialNo === "1") {
data.subArray = data.subArray.filter((subDetails) => {
return subDetails.id === "5" ? undefined : subDetails;
})
}
return data;
});
console.log(Details);
One map plus object constructor:
const arr = [
{ "serialNo": "1", "text": "AAA", "subArray": [{ "id": "1", "name": "geo" }, { "id": "5", "name": "gau" }, { "id": "4", "name": "joi" }] },
{ "serialNo": "2", "text": "BBB", "subArray": [{ "id": "7", "name": "rom" }, { "id": "5", "name": "dom" }, { "id": "4", "name": "noi" }] },
{ "serialNo": "3", "text": "CCC", "subArray": [{ "id": "1", "name": "glo" }, { "id": "5", "name": "gum" }, { "id": "4", "name": "lom" }] }
];
const s = 1, id = 5; // conditions
const r = arr.map(e => (e.serialNo == s)
? Object.assign(e, {'subArray': e.subArray.filter(a => a.id != id)})
: e);
console.log(JSON.stringify(r, null, 2));
Object.assign swaps old subArray with the new filtered one.

Kendo UI HierarchicalDataSource for Treeview with dynamic schema

I'm trying to display a Kendo treeview thanks to a HierarchicalDataSource.
It's a simple region, country, city hierarchy but the difficulty comes with the fact that we have 3 possible levels of regions and countries can appear at the second or at the third level.
Basically,
- First level of regions contains only other regions
- Second level of regions contains other regions or countries
- Third level of regions contains only countries
Here are my schemas:
var portsSchema = {
schema: {
data: "PortList",
model: {
id: "Code"
}
}
};
var countrySchema = {
schema: {
data: "CountryList",
model: {
id: "Code",
children: portsSchema
}
}
};
var regionCountrySchema = {
schema: {
data: "RegionList",
model: {
id: "id",
children: countrySchema
}
}
};
var regionSchema = {
schema: {
data: "RegionList",
model: {
id: "id",
children: regionCountrySchema
}
}
};
Depending on the fact that the region has countries or not, I would like to specify a specific type of children (regionSchema or regionCountrySchema).
var tvDataSource = new kendo.data.HierarchicalDataSource({
data: regions,
schema: {
model: function (data) {
**how to return the right children schema ?**
}
}
});
Returning { children: regionSchema } or {children: regionCountrySchema } triggers a js kendo error.
Any idea to achieve this ? Thank you.
JSON data sample below.
[
{
"Id": 1,
"Name": "MIDDLE EAST AND RED SEA",
"RegionList": [
{
"Id": 12,
"Name": "MIDDLE EAST",
"RegionList": [
{
"Id": 45,
"Name": "M. EAST",
"RegionList": [
],
"CountryList": [
{
"Id": 12007,
"Code": "AE",
"Name": "UAE",
"PortList": [
{
"Id": 6005,
"Code": "AEJEA",
"Name": "JEBEL ALI"
},
{
"Id": 16014,
"Code": "AEAJM",
"Name": "AJMAN"
},
{
"Id": 16015,
"Code": "AEAUH",
"Name": "ABU DHABI"
},
{
"Id": 15109,
"Code": "AEKLF",
"Name": "KHOR AL FAKKAN"
},
{
"Id": 15001,
"Code": "AERKT",
"Name": "RAS AL KHAIMAH"
},
{
"Id": 16018,
"Code": "AESHJ",
"Name": "SHARJAH"
},
{
"Id": 14863,
"Code": "AEQIW",
"Name": "UMM AL QAIWAIN"
},
{
"Id": 15647,
"Code": "AEFJR",
"Name": "AL - FUJAYRAH"
}
]
},
{
"Id": 12018,
"Code": "OM",
"Name": "OMAN",
"PortList": [
{
"Id": 6011,
"Code": "OMSLL",
"Name": "SALALAH"
},
{
"Id": 16218,
"Code": "OMSOH",
"Name": "SOHAR"
}
]
},
{
"Id": 10069,
"Code": "BH",
"Name": "BAHRAIN",
"PortList": [
{
"Id": 15345,
"Code": "BHKBS",
"Name": "BAHRAIN"
}
]
},
{
"Id": 62292,
"Code": "IQ",
"Name": "IRAQ",
"PortList": [
{
"Id": 15383,
"Code": "IQBSR",
"Name": "BASRA"
},
{
"Id": 14673,
"Code": "IQUQR",
"Name": "UMM QASR PT"
}
]
},
{
"Id": 62291,
"Code": "IR",
"Name": "IRAN, ISLAMIC REPUBLIC OF",
"PortList": [
{
"Id": 15250,
"Code": "IRBKM",
"Name": "BANDAR KHOMEINI"
},
{
"Id": 15249,
"Code": "IRBND",
"Name": "BANDAR ABBAS"
},
{
"Id": 14973,
"Code": "IRBUZ",
"Name": "BUSHEHR"
},
{
"Id": 14671,
"Code": "IRKHO",
"Name": "KHORRAMSHAHR"
}
]
},
{
"Id": 62306,
"Code": "KW",
"Name": "KUWAIT",
"PortList": [
{
"Id": 15810,
"Code": "KWSAA",
"Name": "SHUAIBA"
},
{
"Id": 15811,
"Code": "KWSWK",
"Name": "SHUWAIKH"
}
]
},
{
"Id": 12002,
"Code": "SA",
"Name": "SAUDI ARABIA",
"PortList": [
{
"Id": 15039,
"Code": "SAJUB",
"Name": "JUBAIL"
},
{
"Id": 16147,
"Code": "SADMM",
"Name": "AD DAMMAM"
}
]
},
{
"Id": 62364,
"Code": "QA",
"Name": "QATAR",
"PortList": [
{
"Id": 15739,
"Code": "QADOH",
"Name": "DOHA"
},
{
"Id": 14795,
"Code": "QAMES",
"Name": "MESAIEED"
}
]
}
]
}
],
"CountryList": [
]
},
{
"Id": 30,
"Name": "RED SEA",
"RegionList": [
{
"Id": 65,
"Name": "RED SEA",
"RegionList": [
],
"CountryList": [
]
}
],
"CountryList": [
{
"Id": 12002,
"Code": "SA",
"Name": "SAUDI ARABIA",
"PortList": [
{
"Id": 6003,
"Code": "SAKAC",
"Name": "KING ABDULLAH PORT"
},
{
"Id": 15731,
"Code": "SAJED",
"Name": "JEDDAH"
}
]
},
{
"Id": 10114,
"Code": "DJ",
"Name": "DJIBOUTI",
"PortList": [
{
"Id": 8059,
"Code": "DJJIB",
"Name": "DJIBOUTI"
}
]
},
{
"Id": 10122,
"Code": "ER",
"Name": "ERITREA",
"PortList": [
{
"Id": 15031,
"Code": "ERMSW",
"Name": "MASSAWA"
}
]
},
{
"Id": 62300,
"Code": "JO",
"Name": "JORDAN",
"PortList": [
{
"Id": 14801,
"Code": "JOAQJ",
"Name": "AL \u0027AQABAH"
}
]
},
{
"Id": 50001,
"Code": "SD",
"Name": "sd",
"PortList": [
{
"Id": 15734,
"Code": "SDPZU",
"Name": "PORT SUDAN"
}
]
},
{
"Id": 62425,
"Code": "YE",
"Name": "YEMEN",
"PortList": [
{
"Id": 15302,
"Code": "YEHOD",
"Name": "HODEIDAH"
},
{
"Id": 15304,
"Code": "YEMKX",
"Name": "MUKALLA"
},
{
"Id": 15300,
"Code": "YEADE",
"Name": "ADEN"
}
]
},
{
"Id": 10118,
"Code": "EG",
"Name": "EGYPT",
"PortList": [
{
"Id": 16030,
"Code": "EGSOK",
"Name": "SOKHNA PORT"
}
]
}
]
}
],
"CountryList": [
]
}
]

Underscore Create array of objects from JSON object

I have following JSON structure:
{
"shops": {
"categories": {
"cat_1": {
"id": "1",
"label": "Men's Fashions",
"Brands": [{
"id": "2",
"name": "Smith"
}]
},
"cat_2": {
"id": "2",
"label": "Restaurants",
"Brands": [{
"id": "3",
"name": "KFC"
}, {
"id": "4",
"name": "SUBWAY"
}, {
"id": "5",
"name": "MLD"
}, {
"id": "6",
"name": "THAI"
}]
},
"cat_3": {
"id": "3",
"label": "Specialty Shops",
"Brands": [{
"id": "7",
"name": "BODY SHOP"
}]
}
}
}
}
I'd like to achieve something like this:
[{
"categoryid": "1",
"id": "2",
"label": "Men's Fashions",
"name": "Smith"
},
{
"categoryid": "2",
"id": "3",
"label": "Restaurants",
"name": "KFC"
},
{
"categoryid": "2",
"id": "4",
"label": "Restaurants",
"name": "SUBWAY"
},
{
"categoryid": "2",
"id": "5",
"label": "Restaurants",
"name": "MLD"
},
{
"categoryid": "2",
"id": "6",
"label": "Restaurants",
"name": "THAI"
}, {
"categoryid": "3",
"id": "7",
"label": "Specialty Shops",
"name": "BODY SHOP"
},
]
Is there an elegant way to achieve it using underscore?
I tried to use nested _.each() to do that, but feel there might be something better.
generateArray: function(obj) {
var newResult = [];
_.each(obj.categories, function(c) {
_.each(c.Brands, function(d) {
newResult.push({
"categoryid": c.id,
"id": d.id,
"label": c.label,
"name": d.name
});
});
});
return newResult;
}
Anyone can advise me which way is more efficiency at running time?
mine or #Artyom Neustroev or #Anthony Chu ?
You don't really need underscore for that task. Use simple for .. in .. and for (...) loops:
var json = {...};
var result = [];
for (var catKey in json.shops.categories) {
var currentCategory = json.shops.categories[catKey];
for (var i = 0; i < currentCategory.Brands.length; i++) {
var currentBrand = currentCategory.Brands[i];
result.push({
categoryid: currentCategory.id,
label: currentCategory.label,
id: currentBrand.id,
name: currentBrand.name
});
}
}
Fiddle here
Instead of each()'s, here's a way to do it with map()'s...
var output = _.chain(input.shops.categories)
.map(function (category) {
return _(category.Brands).map(function (brand) {
return { categoryId: category.id,
id: brand.id,
label: category.label,
name: brand.name
};
});
}).flatten().value();
JSFIDDLE

Categories

Resources