I have an array like the one shown below. I need to limit the number of objects in the array with ord:1 to 5. How can I to limit the number of objects inside an array based on ord property?
[{"id":"typeahead-86-4951-option-0","label":"Spigen Samsung GS5
Case","model":{"ord":1,"short_description":"Samsung Galaxy S5"}},
{"id":"typeahead-86-4951-option-1","label":"Spigen iPhone 5/5s
Case","model":{"ord":1,"short_description":"iPhone 5 and 5s"}},
{"id":"typeahead-86-4951-option-2","label":"Earphones","model":
{"ord":1,"short_description":"Buy earphones"}},
{"id":"typeahead-86-4951-option-5","label":"Web Conferencing","model":
{"ord":1,"short_description":"Request"}},
{"id":"typeahead-86-4951-option-6","label":"Dreamweaver","model":
{"ord":1,"short_description":null}},
{"id":"typeahead-86-4951-option-7","label":"SSL Certification","model":
{"ord":1,"short_description":"Do you need to update"}},
{"id":"typeahead-86-4951-option-8","label":"Access","model":
{"ord":1,"short_description":"Microsoft Access"}},
{"id":"typeahead-86-4951-option-9","label":"Fireworks","model":
{"ord":1,"short_description":"Adobe Systems Fireworks"}},
{"id":"typeahead-86-4951-option-10","label":"Spigen iPhone 6 Case","model":
{"ord":1,"short_description":"For iPhone 6"}},
{"id":"typeahead-86-4951-option-11","label":"What is a cookie?
\t\t","model":{"ord":4,"short_description":"What is a cookie?\t\t"}},
{"id":"typeahead-86-4951-option-12","label":"What are phishing scams and
how can I avoid them?\n\t\t","model":{"ord":4,"short_description":"What
are phishing"}},
{"id":"typeahead-86-4951-option-13","label":"How to Deal with
Spam","model":{"ord":4,"short_description":"How to Deal with Spam"}},
{"id":"typeahead-86-4951-option-14","label":"What is Spam?","model":
{"ord":4,"short_description":"What is Spam?}},
{"id":"typeahead-86-4951-option-15","label":"How to set\n\t\t","model":
{"ord":4,"short_description":"How\n\t\t"}}
]
You can create dictionary with ord values as keys and store there up to 5 items.In the end just concat all arrays in dictionary.
let input = [{
"id": "typeahead-86-4951-option-0",
"label": "Spigen Samsung GS5 Case",
"model": {
"ord": 1,
"short_description": "Samsung Galaxy S5"
}
}, {
"id": "typeahead-86-4951-option-1",
"label": "Spigen iPhone 5/5s Case",
"model": {
"ord": 1,
"short_description": "iPhone 5 and 5s"
}
},
{
"id": "typeahead-86-4951-option-2",
"label": "Earphones",
"model": {
"ord": 1,
"short_description": "Buy earphones"
}
},
{
"id": "typeahead-86-4951-option-5",
"label": "Web Conferencing",
"model": {
"ord": 1,
"short_description": "Request"
}
},
{
"id": "typeahead-86-4951-option-6",
"label": "Dreamweaver",
"model": {
"ord": 1,
"short_description": null
}
},
{
"id": "typeahead-86-4951-option-7",
"label": "SSL Certification",
"model": {
"ord": 1,
"short_description": "Do you need to update"
}
},
{
"id": "typeahead-86-4951-option-8",
"label": "Access",
"model": {
"ord": 1,
"short_description": "Microsoft Access"
}
},
{
"id": "typeahead-86-4951-option-9",
"label": "Fireworks",
"model": {
"ord": 1,
"short_description": "Adobe Systems Fireworks"
}
},
{
"id": "typeahead-86-4951-option-10",
"label": "Spigen iPhone 6 Case",
"model": {
"ord": 1,
"short_description": "For iPhone 6"
}
},
{
"id": "typeahead-86-4951-option-11",
"label": "What is a cookie?\t\t",
"model": {
"ord": 4,
"short_description": "What is a cookie?\t\t"
}
},
{
"id": "typeahead-86-4951-option-12",
"label": "What are phishing scams and how can I avoid them?\n\t\t",
"model": {
"ord": 4,
"short_description": "What are phishing"
}
},
{
"id": "typeahead-86-4951-option-13",
"label": "How to Deal with Spam",
"model": {
"ord": 4,
"short_description": "How to Deal with Spam"
}
},
{
"id": "typeahead-86-4951-option-14",
"label": "What is Spam?",
"model": {
"ord": 4,
"short_description": "What is Spam?"
}
},
{
"id": "typeahead-86-4951-option-15",
"label": "How to set\n\t\t",
"model": {
"ord": 4,
"short_description": "How\n\t\t"
}
}
],
ordObj;
ordObj = input.reduce(function(acc, el) {
let ord = el.model.ord;
if (!acc.hasOwnProperty(ord)) {
acc[ord] = [];
}
if (acc[ord].length < 5) {
acc[ord].push(el);
}
return acc;
}, {});
let result = Object.values(ordObj).reduce((acc, el) => (acc.concat(el)), []);
console.log(result);
You can use a small loop like this, counting how many "ord":1 you keep, and stopping after 5 :
let input = [
{"id":"typeahead-86-4951-option-0","label":"Spigen Samsung GS5 Case","model":{"ord":1,"short_description":"Samsung Galaxy S5"}}, {"id":"typeahead-86-4951-option-1","label":"Spigen iPhone 5/5s Case","model":{"ord":1,"short_description":"iPhone 5 and 5s"}},
{"id":"typeahead-86-4951-option-2","label":"Earphones","model": {"ord":1,"short_description":"Buy earphones"}},
{"id":"typeahead-86-4951-option-5","label":"Web Conferencing","model": {"ord":1,"short_description":"Request"}},
{"id":"typeahead-86-4951-option-6","label":"Dreamweaver","model": {"ord":1,"short_description":null}},
{"id":"typeahead-86-4951-option-7","label":"SSL Certification","model":{"ord":1,"short_description":"Do you need to update"}},
{"id":"typeahead-86-4951-option-8","label":"Access","model": {"ord":1,"short_description":"Microsoft Access"}},
{"id":"typeahead-86-4951-option-9","label":"Fireworks","model": {"ord":1,"short_description":"Adobe Systems Fireworks"}},
{"id":"typeahead-86-4951-option-10","label":"Spigen iPhone 6 Case","model": {"ord":1,"short_description":"For iPhone 6"}},
{"id":"typeahead-86-4951-option-11","label":"What is a cookie?\t\t","model":{"ord":4,"short_description":"What is a cookie?\t\t"}},
{"id":"typeahead-86-4951-option-12","label":"What are phishing scams and how can I avoid them?\n\t\t","model": {"ord":4,"short_description":"What are phishing"}},
{"id":"typeahead-86-4951-option-13","label":"How to Deal with Spam","model":{"ord":4,"short_description":"How to Deal with Spam"}},
{"id":"typeahead-86-4951-option-14","label":"What is Spam?","model": {"ord":4,"short_description":"What is Spam?"}},
{"id":"typeahead-86-4951-option-15","label":"How to set\n\t\t","model": {"ord":4,"short_description":"How\n\t\t"}}
],
output = [],
count = 0;
input.forEach( obj => {
if(obj.model.ord===1){
if(count>=5) return
count++
}
output.push(obj)
})
console.log("Count before : " + input.filter(o=>o.model.ord===1).length )
console.log("Count after : " + output.filter(o=>o.model.ord===1).length )
To achieve expected result, use filter methos to filter out order:1 records and slice array methods to get first 5
let final = arr.filter(v => v.model.ord === 1).slice(0, 5);
codepen - https://codepen.io/nagasai/pen/NOmXar?editors=1010
let arr = [{"id":"typeahead-86-4951-option-0","label":"Spigen Samsung GS5 Case","model":{"ord":1,"short_description":"Samsung Galaxy S5"}},
{"id":"typeahead-86-4951-option-1","label":"Spigen iPhone 5/5s Case","model":{"ord":1,"short_description":"iPhone 5 and 5s"}},
{"id":"typeahead-86-4951-option-2","label":"Earphones","model":
{"ord":1,"short_description":"Buy earphones"}},
{"id":"typeahead-86-4951-option-5","label":"Web Conferencing","model":
{"ord":1,"short_description":"Request"}},
{"id":"typeahead-86-4951-option-6","label":"Dreamweaver","model":
{"ord":1,"short_description":null}},
{"id":"typeahead-86-4951-option-7","label":"SSL Certification","model":
{"ord":1,"short_description":"Do you need to update"}},
{"id":"typeahead-86-4951-option-8","label":"Access","model":
{"ord":1,"short_description":"Microsoft Access"}},
{"id":"typeahead-86-4951-option-9","label":"Fireworks","model":
{"ord":1,"short_description":"Adobe Systems Fireworks"}},
{"id":"typeahead-86-4951-option-10","label":"Spigen iPhone 6 Case","model":
{"ord":1,"short_description":"For iPhone 6"}},
{"id":"typeahead-86-4951-option-11","label":"What is a cookie? \t\t","model":{"ord":4,"short_description":"What is a cookie?\t\t"}},
{"id":"typeahead-86-4951-option-12","label":"What are phishing scams and how can I avoid them?\n\t\t","model":{"ord":4,"short_description":"What are phishing"}},
{"id":"typeahead-86-4951-option-13","label":"How to Deal with Spam","model":{"ord":4,"short_description":"How to Deal with Spam"}},
{"id":"typeahead-86-4951-option-14","label":"What is Spam?","model": {"ord":4,"short_description":"What is Spam?"}},
{"id":"typeahead-86-4951-option-15","label":"How to set\n\t\t","model": {"ord":4,"short_description":"How\n\t\t"}}]
let final = arr.filter(v => v.model.ord === 1).slice(0, 5);
console.log(final)
You can create something similar to what I below as tracker. Use that variable to keep a count of items by ord. In my example below, I am using Array.prototype.filter on your original array of data below. Each time the callback encounters an array element with an ord property equal to five, the tracker count is incremented. If the count is less than 5 we can add it to our new array, if not, skip it.
var tracker = (function(i) {
var c = i;
return {
value: () => c,
increment: () => c += 1,
decrement: () => c -= 1
}
})(0);
var data = [{
id: 'item0',
ord: 1
}, {
id: 'item1',
ord: 1
}, {
id: 'item2',
ord: 1
}, {
id: 'item3',
ord: 1
}, {
id: 'item4',
ord: 1
}, {
id: 'item5',
ord: 1
}, {
id: 'item6',
ord: 1
}, {
id: 'item7',
ord: 1
}, {
id: 'item8',
ord: 1
}, {
id: 'item9',
ord: 2
}, {
id: 'item10',
ord: 2
}, {
id: 'item11',
ord: 2
}, {
id: 'item12',
ord: 2
}];
var limited = data.filter(el => {
if (el.ord === 1) {
tracker.increment();
if (tracker.value() < 6) {
return true;
}
return false;
}
return true;
});
console.log(limited);
Related
I get a list of items with add-ons from the server, but when I try to delete an add-on from this list I can't. I noticed that when I try to access the property grupoAdicionais.produto.codigo, it does not exist because it has a sublevel coming from the API, how do I remove this to have access to my product.codigo?
Array received from API:
"grupoAdicionais":[
{"produto": {"codigo":21, "descricao":"Bacon"}, "item":148657, "quantidade":1, "total":5},
{"produto": {"codigo":13193, "descricao":"Queijo"}, "item":148657, "quantidade":1, "total":1}
]
My code in the reducer to return the list without the extra:
REMOVER_ADICIONAL: (state, action) => {
let itemRemover = action.item;
let listaReducer = state.lstItensRestauranteQRcode;
const itemRemovido = listaReducer.filter((item) => {
return item.grupoAdicionais.produto.codigo != itemRemover.produto.codigo;
});
state.lstItensRestauranteQRcode = itemRemovido;
},
If all you want to do is get a list of the codes:
const response = {"grupoAdicionais": [{
"produto": {
"codigo": 21,
"descricao": "Bacon"
},
"item": 148657,
"quantidade": 1,
"total": 5
}, {
"produto": {
"codigo": 13193,
"descricao": "Queijo"
},
"item": 148657,
"quantidade": 1,
"total": 1
}]}
const codigos = response.grupoAdicionais.map(grupo => grupo.produto.codigo)
console.log(codigos)
// =>
[ 21, 13193 ]
I'm not totally sure, but it seems like maybe you want to remove a group by its code.
const removeByCode = (code) => response.grupoAdicionais.filter((group) => group.produto.codigo !== code)
const newGroups = removeByCode(21)
console.log(newGroups)
// =>
[
{
produto: { codigo: 13193, descricao: 'Queijo' },
item: 148657,
quantidade: 1,
total: 1
}
]
var response = {"grupoAdicionais": [{
"produto": {
"codigo": 21,
"descricao": "Bacon"
},
"item": 148657,
"quantidade": 1,
"total": 5
}, {
"produto": {
"codigo": 13193,
"descricao": "Queijo"
},
"item": 148657,
"quantidade": 1,
"total": 1
}]}
console.dir(response.grupoAdicionais[0].produto.codigo)
grupoAdicionais is an array here, you have to access it like this:
console.dir(response.grupoAdicionais[0].produto.codigo)
I have two arrays:
const array1 = [{
"id": "4521",
"name": "Tiruchirapalli",
"stateId": "101"
},
{
"id": "1850",
"name": "Tenkasi",
"stateId": "101"
},
{
"id": "202",
"name": "Thanjavur",
"stateId": "101"
},
{
"id": "505",
"name": "Ernakulam",
"stateId": "102"
},
];
And now array2
const array2 = [{
"id": 1850,
"cityName": "Tenkasi",
"aliasNames": [
"Thenkasi"
]
},
{
"id": 4521,
"cityName": "Tiruchirapalli",
"aliasNames": [
"Trichy"
]
},
{
"id": 202,
"cityName": "Thanjavur",
"aliasNames": [
"Tanjore"
]
},
{
"id": 505,
"cityName": "Ernakulam",
"aliasNames": [
"Kochi",
"Cochin"
]
},
];
what i need to do is, how to filter both the arrays at same time ( or filter first one and then second which ever one is performance effective ).
For instance, when user types "Kochi", first it should check on array1 to find if its has name="Kochi", if it has then we can set the state with that and if it doesnt have we need to find it on array2 and the update the state !
Which is fast and effective way to handle this - ( array1 has 2500 records and array2 has 990 records ) so performance / speed is also a concern
My attempt:
searchFilterFunction = text => {
this.setState({ typedText: text });
const newData = array1.filter(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({ data: newData});
};
How to implement the second filter in optimized way ?
For instance, when user types "Kochi", first it should check on array1
to find if its has name="Kochi", if it has then we can set the state
with that and if it doesnt have we need to find it on array2 and the
update the state !
I would do something like this with Array.find.
if( array1.find(item=>item.name.toUpperCase() === text) ) {
// set state
} else if( array2.find(item=>item.cityName.toUpperCase() === text) ) {
// set state
}
A refined form would be
let result = array1.find(item=>item.name.toUpperCase() === text);
// check in array 2 as we cannot find in array 1
if(!result) {
result = array2.find(item=>{
// check in aliasNames and in cityName
return item.cityName.toUpperCase() === text || item.aliasNames.includes(text);
}
);
}
if(result) {
setState(result);
} else {
// place not found
}
Regarding the performance based on your array count you will not see much difference. If you want to save some milliseconds you can check the array with least count first as mentioned in one of the comments. But the time also varies based on were the element is in array.
I think this is the most optimal solution because nesting the two filter won't work as you need to filter from first array and then second.
const array1 = [{
"id": "4521",
"name": "Tiruchirapalli",
"stateId": "101"
},
{
"id": "1850",
"name": "Tenkasi",
"stateId": "101"
},
{
"id": "202",
"name": "Thanjavur",
"stateId": "101"
},
{
"id": "505",
"name": "Ernakulam",
"stateId": "102"
},
];
const array2 = [{ "id": 1850, "cityName": "Tenkasi",
"aliasNames": [
"Thenkasi"
]
},{"id": 4521,"cityName": "Tiruchirapalli",
"aliasNames": [
"Trichy"
]
},
{
"id": 202,
"cityName": "Thanjavur",
"aliasNames": [
"Tanjore"
]
},
{
"id": 505,
"cityName": "Ernakulam",
"aliasNames": [
"Kochi",
"Cochin"
]
},
];
function filter(text) {
// Complexity Linear
const filter_array = array1.filter((a) => {
return (a.name === text)
});
if (filter_array.length > 0) {
//Set State and return
}
//Complexity Linear and includes complexity Linear O(sq(m*n)) where n is //the aliasName record
const filter_array2 = array2.filter((a) => {
return a.cityName === text || a.aliasNames.includes(text);
});
return filter_array2 //Set State filter array 2
}
console.log(filter("Kochi"));
I have a dynamic table with dynamic inputs. Each input has an unique number added to the end of the model name. There are 10 inputs per table with the last being the total. I need to watch the first 9 inputs and calculate the sum. Here is what the json looks like after dynamically assigning unique model names.
[
{
"section_id": 3155,
"subdivision_id": 3500,
"section_name": "Ph 1(P)-Mercedes",
"sectionInputs": [
{
"model": "price_min-3155"
},
{
"model": "price_max-3155"
},
{
"model": "units_occ-3155"
},
{
"model": "inv_mod-3155"
},
{
"model": "inv_fin-3155"
},
{
"model": "inv_vdl-3155"
},
{
"model": "inv_uc-3155"
},
{
"model": "inv_fut-3155"
},
{
"model": "inv_con-3155"
},
{
"model": "units_total-3155"
}
]
},
{
"section_id": 12863,
"subdivision_id": 3500,
"section_name": "Ph 1(P)-Adams",
"sectionInputs": [
{
"model": "price_min-12863"
},
{
"model": "price_max-12863"
},
{
"model": "units_occ-12863"
},
{
"model": "inv_mod-12863"
},
{
"model": "inv_fin-12863"
},
{
"model": "inv_vdl-12863"
},
{
"model": "inv_uc-12863"
},
{
"model": "inv_fut-12863"
},
{
"model": "inv_con-12863"
},
{
"model": "units_total-12863"
}
]
},
{
"section_id": 16152,
"subdivision_id": 3500,
"section_name": "Ph 1(P)-Unassigned",
"sectionInputs": [
{
"model": "price_min-16152"
},
{
"model": "price_max-16152"
},
{
"model": "units_occ-16152"
},
{
"model": "inv_mod-16152"
},
{
"model": "inv_fin-16152"
},
{
"model": "inv_vdl-16152"
},
{
"model": "inv_uc-16152"
},
{
"model": "inv_fut-16152"
},
{
"model": "inv_con-16152"
},
{
"model": "units_total-16152"
}
]
}
]
The units_total needs to hold the sum value for each array. I was looking at using a watchgroup function but not sure how I could do this with possibly needing a for loop? I'm open to suggestions on the best way to handle this. javascript, jquery, lodash, linq.js are what is currently being used in project.
Here is
working plunker
$scope.model = {};
function prepareDataForView() {
for (var i = 0; i < sections.length; i++) {
sections[i].sectionInputs = sectionInputSvc.sectionInputs(sections[i]);
sections[i].sectionInputLabels = sectionInputLabels;
}
$scope.sections = sections;
}
prepareDataForView();
One way to implement this is to calculate the total whenever input ng-changes:
var sum = function(acc,cur){ return acc+cur; }
$scope.modelChanged = function(section, input){
var inputsCount = section.sectionInputs.length;
var totalInput = section.sectionInputs[inputsCount-1];
if(input === totalInput){
return;
}
var total = section.sectionInputs.slice(0, inputsCount - 1).map(function(input){
return $scope.model[input.model];
}).filter(angular.isDefined).reduce(sum, 0);
$scope.model[totalInput.model] = total;
};
Which can then be invoked on each input:
<input ng-model="model[input.model]" ng-change="modelChanged(section, input)" type="number" />
Here's an updated plunker.
Well, I have solved it with jQuery, maybe this answer doesn't fit you because it's inconsistent with your angular app, but I hope it can be helpful to someone else.
$(document).on("change", "input", function()
{
$tr = $(this).parent().parent();
$tds = $tr.find("td");
var sum = 0;
$.each($tds, function(index, td){
var valueInput = $(td).find("input").val();
if(index < 9 ){
sum += parseFloat((valueInput != "") ? valueInput : 0 );
}
});
$tds.eq(9).find("input").val(sum);
});
Here is the updated plunker
I have this js object
{
"2015": {
"11": {
"10": {
"Family & Friends\nGames": {
"c": 2
},
"Collectible\nGames": {
"c": 1
},
"Logic Games\n": {
"c": 1
},
"Kids Games\n": {
"c": 1
}
},
},
"Family & Friends\nGames": {
"c": 9
},
"Collectible\nGames": {
"c": 2
},
"Logic Games\n": {
"c": 4
},
"Kids Games\n": {
"c": 6
},
"Classic Games\n": {
"c": 3
},
"Preschool\nGames": {
"c": 5
}
},
"meta": {
"id": [
"[CLY]2",
"[CLY]7",
"[CLY]6",
"[CLY]1",
"[CLY]4",
"[CLY]3"
],
"segments": [
"id",
"title"
],
"title": [
"Family & Friends\nGames",
"Collectible\nGames",
"Logic Games\n",
"Kids Games\n",
"Classic Games\n",
"Preschool\nGames"
]
}
}
Im trying to subtract the same objects right above "meta" that match the keys under "title". I accomplished this using ruby with the following code
results = JSON.parse(resp.body)
data = results["2015"]
title = results["meta"]["title"]
alg = data.slice(*title).to_a
info = alg.sort_by { |k,v| v["c"] }
So I tried to convert the object into an array and from there slice all the content that matches the other array name title and finally sort the information based on their "c" value.
none of this seems to work for me so I have tried to get the data from the object using [] and the name of the key inside, but since each name under the array "title" has \n makes me has to add an extra \ to access it. I want this to be dynamic and not have to modify it every time I have different names under "title"
I need something like this https://jsfiddle.net/7chntms2/6/
Thank you for the help
Is this what you are trying to achieve?
var obj = {
"2015": {
"11": {
"10": {
"Family & Friends\nGames": {
"c": 2
},
"Collectible\nGames": {
"c": 1
},
"Logic Games\n": {
"c": 1
},
"Kids Games\n": {
"c": 1
}
},
},
"Family & Friends\nGames": {
"c": 9
},
"Collectible\nGames": {
"c": 2
},
"Logic Games\n": {
"c": 4
},
"Kids Games\n": {
"c": 6
},
"Classic Games\n": {
"c": 3
},
"Preschool\nGames": {
"c": 5
}
},
"meta": {
"id": [
"[CLY]2",
"[CLY]7",
"[CLY]6",
"[CLY]1",
"[CLY]4",
"[CLY]3"
],
"segments": [
"id",
"title"
],
"title": [
"Family & Friends\nGames",
"Collectible\nGames",
"Logic Games\n",
"Kids Games\n",
"Classic Games\n",
"Preschool\nGames"
]
}
}
var keys = obj["meta"]["title"];
var newObj = [];
for (var i = 0; i < keys.length; i++) {
newObj.push({
name: keys[i],
content: obj["2015"][keys[i]]
});
}
newObj.sort(function(a, b) {
if (a.content.c < b.content.c) return -1;
if (a.content.c > b.content.c) return 1;
return 0;
});
console.log(newObj);
Example fiddle: https://jsfiddle.net/wv2kbcyn/
Basically, if the name of that JSON object is data:
var meta = data["meta"];
var titles = meta["title"];
var logicgames = titles[2];
You can also loop the titles:
for(var key in titles)
{
var title = titles[key];
console.log(title); // "Family & Friends\nGames", ...
}
So titles is an array now.
This is my saved localstorage,
[{"industry_Id":1,"merchant_id":2}]
I want to filter below result, to get HP.
{
"industries": [
{
"id": 1,
"name": "oil and gas",
"merchant": [
{
"id": 1,
"name": "ABC",
},
{
"id": 2,
"name": "DEF",
},
{
"id": 3,
"name": "GHJ",
}
]
},
{
"id": 2,
"name": "IT",
"merchant": [
{
"id": 1,
"name": "Apple",
},
{
"id": 2,
"name": "HP",
},
{
"id": 3,
"name": "Google",
}
]
}
]
}
I thought of using multiple $.each but it have to iterate few times and it's quite redundant.
I would prefer using Javascript for loop, that way you can skip iterating over every object once required element is found.
Without jQuery (using for)
var i, j, merchant = null;
for(i = 0; i < data['industries'].length; i++){
if(data['industries'][i]['id'] == arg[0]['industry_Id']){
for(j = 0; j < data['industries'][i]['merchant'].length; j++){
if(data['industries'][i]['merchant'][j]['id'] == arg[0]['merchant_id']){
merchant = data['industries'][i]['merchant'][j];
break;
}
}
if(merchant !== null){ break; }
}
}
With jQuery (using $.each)
var merchant_found = null;
$.each(data['industries'], function(i, industry){
if(industry['id'] == arg[0]['industry_Id']){
$.each(industry['merchant'], function(i, merchant){
if(merchant['id'] == arg[0]['merchant_id']){
merchant_found = merchant;
}
return (!merchant_found);
});
}
return (!merchant_found);
});
var arg = [{"industry_Id":1,"merchant_id":2}];
var data = {
"industries": [
{
"id": 1,
"name": "oil and gas",
"merchant": [
{
"id": 1,
"name": "ABC",
},
{
"id": 2,
"name": "DEF",
},
{
"id": 3,
"name": "GHJ",
}
]
},
{
"id": 2,
"name": "IT",
"merchant": [
{
"id": 1,
"name": "Apple",
},
{
"id": 2,
"name": "HP",
},
{
"id": 3,
"name": "Google",
}
]
}
]
};
var i, j, merchant = null;
for(i = 0; i < data['industries'].length; i++){
if(data['industries'][i]['id'] == arg[0]['industry_Id']){
for(j = 0; j < data['industries'][i]['merchant'].length; j++){
if(data['industries'][i]['merchant'][j]['id'] == arg[0]['merchant_id']){
merchant = data['industries'][i]['merchant'][j];
break;
}
}
if(merchant !== null){ break; }
}
}
console.log(merchant);
document.writeln("<b>Without jQuery:</b><br>");
document.writeln((merchant !== null) ? "Found " + merchant['name'] : "Not found");
var merchant_found = null;
$.each(data['industries'], function(i, industry){
if(industry['id'] == arg[0]['industry_Id']){
$.each(industry['merchant'], function(i, merchant){
if(merchant['id'] == arg[0]['merchant_id']){
merchant_found = merchant;
}
return (!merchant_found);
});
}
return (!merchant_found);
});
console.log(merchant_found);
document.writeln("<br><br><b>With jQuery:</b><br>");
document.writeln((merchant_found) ? "Found " + merchant_found['name'] : "Not found");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
selectors.map(function(selector) {
return data.industries.filter(function(industry) {
return industry.id == selector.industry_Id;
})[0].merchant.filter(function(merchant) {
return merchant.id == selector.merchant_id;
})[0].name;
});
// => DEF
If you want "HP", you want industry 2, not industry 1.
.filter(...)[0] is not really optimal. You could use .find(...), but that is not yet universally supported. Or you could use plain old JavaScript and write for loops instead to make it fast. Or you could use objects with ID keys instead of arrays to make lookups faster.
When it comes into a position where collection of data is what you're processing, I suggest you to take a look at underscore.js. It's not optimal choice for the best performance but it does make you code more readable and makes more sense especially when compared with loop.
Say data is a variable which stores your JSON data.
Try this:
// Given this selector criteria
var select = [{"industry_Id":1,"merchant_id":2}];
function filterByCriteria(criteria, data){
var match = [];
_.each(criteria, function(crit){
function matchIndustry(rec){ return rec.id===crit.industry_Id }
function matchMerchant(rec){ return rec.id===crit.merchant_id }
// Filter by industry id
var industry = _.first(_.where(data.industry, matchIndustry));
// Filter by merchant id
var merchant = _.where(industry.merchant, matchMerchant);
_.each(merchant, function addToMatchResult(m){
match.push(m.name);
});
});
return match;
}
var filteredData = filterByCriteria(select, data);
From snippet above, any merchants which match the search criteria will be taken to the match list. Is it more readable to you?
Do you even need numerical id's? Gets super easy when you don't.
/*
{
"industry": {
"oil and gas":{
"merchant": {
"ABC": {
"name": "ABC oil"
},
"DEF": {
"name": "DEF gas"
},
"GHJ" :{
"name": "GHJ oil and gas"
}
}
},
"IT": {
"merchant": {
"Apple" : {
"name": "Apple computers"
},
"HP": {
"name": "Hewlett Packard"
},
"Google": {
"name": "Google. Maw haw haw"
}
}
}
}
}
*/
var data = '{"industry": {"oil and gas":{"merchant": {"ABC": {"name": "ABC oil"},"DEF": {"name": "DEF gas"},"GHJ" :{"name": "GHJ oil and gas"}}},"IT": {"merchant": {"Apple" : {"name": "Apple computers"},"HP": {"name": "Hewlett Packard"},"Google": {"name": "Google. Maw haw haw"}}}}}';
data = JSON.parse(data);
var merchant = data.industry['IT'].merchant['HP'];
alert(merchant.name);
//console.log(merchant.name);