Jquery how to query Json Object with multiple where clause - javascript

How do I query multiple columns/properties from a json object?
I am trying this to query single column "category". How can Query with both Category and Id?
var data = {
"items": [{
"id": 1,
"category": ["cat1","cat2"]
}, {
"id": 2,
"category": ["cat1","cat3"]
}, {
"id": 3,
"category": ["cat11","cat2"]
}]
};
var returnedData = $.grep(data.items, function (element) {
return element.category.indexOf('cat1') >= 0;
});
console.log(returnedData);

Instead of using the slower grep, use plain js filter
var data = {
"items": [{
"id": 1,
"category": ["cat1","cat2"]
}, {
"id": 2,
"category": ["cat1","cat3"]
}, {
"id": 3,
"category": ["cat11","cat2"]
}]
};
const res = data.items.filter(e => e.category.indexOf('cat1') >= 0 && e.id === 1);
console.log(res);

Not sure exactly what you are asking but -
return element.category.indexOf('cat1') >= 0 && element.id == 2;

**return element.category.includes('cat1') && element.id!=1;**
This way you can achieve this
var data = {
"items": [{
"id": 1,
"category": ["cat1","cat2"]
}, {
"id": 2,
"category": ["cat1","cat3"]
}, {
"id": 3,
"category": ["cat11","cat2"]
}]
};
var returnedData = $.grep(data.items, function (element) {
return element.category.includes('cat1') && element.id!=1;
});
console.log(returnedData);
Live Demo

Related

How can I inner join with two object arrays in JavaScript?

I need inner join with two array in javascript like this:
array1 =
[
{
"id": 1,
"name": "Tufan"
},
{
"id": 2,
"name": "Batuhan"
},
{
"id": 3,
"name": "Hasan"
}
]
array2 =
[
{
"name": "yyy",
"externalid": "1",
"value": "Asd"
},
{
"name": "aaaa"
"externalid": "2",
"value": "ttt"
}
]
expectedArray =
[
{
"id": 1,
"name": "Tufan",
"externalid": "1",
"value": "Asd"
},
{
"id": 2,
"name": "Batuhan",
"externalid": "2",
"value": "ttt"
}
]
rules:
on: array2.externalid = array1.id
select: array1.id, array1.name, array2.externalid, array2.value
My approach:
array1.filter(e => array2.some(f => f.externalid == e.id));
// I need help for continue
How can I make this?
Doesn't matter information: I use ES5 and pure javascript
You can do it like this:
const res = array2.map((item) => {
const related = array1.find((el) => el.id == item.externalid);
return { ...item, ...related };
});
Using a map to loop over the array2 and a find to get the array1 relative.

How to get immediate parent Id of the child id in array of nested json Object?

I need to get the parent id of the specific child.
Here is my sample JSON, If I give entity id 32 it should return 6 as parent Id and if I give 30 it should return 5 as parent id.
const arr = [{
"id": 0,
"name": "My Entity",
"children": [
{
"id": 1,
"name": "MARKET",
"children": [
{
"id": 2,
"name": "Sales",
"children": [
{
"id": 3,
"name": "District 1",
"children": [
{
"id": 5,
"name": "Area 1",
"children": [
{
"entityId": 30,
"id": 26,
"name": "Mumbai"
},
{
"entityId": 31,
"id": 26,
"name": "Hyderabad"
}
],
"num": 0,
},
{
"id": 6,
"name": "Area 2",
"children": [
{
"entityId": 32,
"id": 32,
"name": "Karnataka"
},
{
"entityId": 33,
"id": 33,
"name": "Andhra Pradesh"
}
],
"num": 0,
},
]
},
]
},
]
},
]
}]
Here is the code I have tried
const findParent = (arr, entityId) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].entityId === entityId) {
return [];
} else if (arr[i].children && arr[i].children.length) {
const t = findParents(arr[i].children, entityId);
if (t !== false) {
t.push(arr[i].id);
return t;
}
}
}
return false;
};
findParents(arr, 30);
But it is returning like below
[
5,
3,
2,
1,
0
]
But I want the output to be
[
5
]
Kindly help me on this, thanks
Replace this:
t.push(arr[i].id);
with:
if (t.length == 0) t.push(arr[i].id);
I would suggest easier solution
const findParent = (arr, entityId) => {
const children = arr.flatMap(parent =>
(item.children || []).map(child => ({ parent, child, entityId: child.entityId }))
)
const res = children.find(item => item.entityId === entityId)
return res.entityId || findChildren(res.map(v => v.child), entityId)
}

Find the parent of the searched value using javascript

I have a JSON data in the following format which needs to be filtered based on a specific value :
[
{
"id": 0,
"name": "ROOT-0",
"childs": [
{
"id": 1,
"name": "ROOT-1",
"childs": [
{
"id": 11,
"name": "ROOT-11",
},
{
"id": 12,
"name": "ROOT-12",
},
]
},
{
"id": 2,
"name": "ROOT-2",
"childs": [
{
"id": 21,
"name": "ROOT-21",
},
{
"id": 22,
"name": "ROOT-22",
},
]
},
{
"id": 3,
"name": "ROOT-3",
"childs": [
{
"id": 31,
"name": "ROOT-31",
},
{
"id": 32,
"name": "ROOT-32",
},
]
}
]
}]
The scenario is that I need to get ROOT-1 as final result if I look for ROOT-11/ROOT-12.
I have tried filtering with this following code
var res = data[0].filter(function f(o) {
if (o.name.includes("ROOT-11")) return o;
})
But I am not able to get a grip on the logic. Is there a way to achieve my desired output
You could use find()...
var result = data[0].childs.find(x => {
return x.childs.find(y => {
return y.name === name;
});
}).name;
Or you could write a function...
function findParentName(name, data) {
return data[0].childs.find(x => {
return x.childs.find(y => {
return y.name === name;
});
}).name;
}
var result = findParentName('ROOT-11', data);
console.log(result);
Doing this will give you the best performance result as find() will return as soon as it finds a match, and not iterate through each remaining loop like forEach() or map()
If you're using ES6 you can say...
const result = data[0].childs.find(x => x.childs.find(y => y.name === 'ROOT-11')).name;
You can grab the item using a few filters and a find, to get the result you are looking for:
let items = [{
"id": 0,
"name": "ROOT-0",
"childs": [{
"id": 1,
"name": "ROOT-1",
"childs": [{
"id": 11,
"name": "ROOT-11",
},
{
"id": 12,
"name": "ROOT-12",
},
]
},
{
"id": 2,
"name": "ROOT-2",
"childs": [{
"id": 21,
"name": "ROOT-21",
},
{
"id": 22,
"name": "ROOT-22",
},
]
},
{
"id": 3,
"name": "ROOT-3",
"childs": [{
"id": 31,
"name": "ROOT-31",
},
{
"id": 32,
"name": "ROOT-32",
},
]
}
]
}]
function find(name) {
let result
items.filter(item =>
result = item.childs.find(item2 =>
item2.childs.filter(i => i.name == name).length > 0
)
)
return result.name || ''
}
console.log(find('ROOT-11'))
console.log(find('ROOT-22'))
console.log(find('ROOT-32'))
You could, for an arbitrary count nested children, use a recusion approach by iterating the actual level and if not found check the children with the actual name.
If the wanted name is found, the parent's name is handed over through all nested calls and returned.
function getParent(array, search, parent) {
return array.some(o => o.name === search || o.children && (parent = getParent(o.children, search, o.name)))
&& parent;
}
var data = [{ id: 0, name: "ROOT-0", children: [{ id: 1, name: "ROOT-1", children: [{ id: 11, name: "ROOT-11" }, { id: 12, name: "ROOT-12" }] }, { id: 2, name: "ROOT-2", children: [{ id: 21, name: "ROOT-21" }, { id: 22, name: "ROOT-22" }] }, { id: 3, name: "ROOT-3", children: [{ id: 31, name: "ROOT-31" }, { id: 32, name: "ROOT-32" }] }] }]
console.log(getParent(data, 'ROOT-0')); // undefined no parent found
console.log(getParent(data, 'ROOT-1')); // ROOT-0
console.log(getParent(data, 'ROOT-11')); // ROOT-1
console.log(getParent(data, 'ROOT-31')); // ROOT-3
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript get data totals into list

I have this data:
{
"id": "123",
"name": "name here",
"thsub": {
"637": {
"id": "637",
"name": "Sub 1",
"stats": {
"items": 5,
},
"ons": null
},
"638": {
"id": "638",
"name": "Sub 2",
"stats": {
"items": 10,
},
"ons": null
}
},
"ph": 10,
}
Here's is the code:
mydata = [mydata];
var chList=[];
var thList=[];
var thCount=[];
for (var i = 0; i < mydata.length; i++) {
var obj = mydata[i];
var cl = obj.name;
if (obj.thsub != null) {
chList.push(cl);
}
if(obj.thsub) {
if (i < 10) {
var nme = Object.keys(obj.thsub).map( function(key){
var item = obj.thsub[key];
return item.name;
});
thCount.push(numberofitems);
thList = thList.concat(nme);
thCount = thCount.concat(Array(nme.length).fill(nme.length));
}
}
}
My problem is in the thCount ... what I need to do is to count each "items" on obj.thsub.638 or other ...stats.items and put the totals into thCount like I've got in thList.
So the desired result woule be 5 and 10 in other words: [5, 10] in this case.
thCount would be [5, 10]
How can I do this?
you should access the json objects using key value, index is for arrays. below code just does the thcount for you
var data = {
"id": "123",
"name": "name here",
"thsub": {
"637": {
"id": "637",
"name": "Sub 1",
"stats": {
"items": 5,
},
"ons": null
},
"638": {
"id": "638",
"name": "Sub 2",
"stats": {
"items": 10,
},
"ons": null
}
},
"ph": 10,
};
var thCount = [];
for(key in data.thsub ){
if(data.thsub[key].stats){
thCount.push(data.thsub[key].stats.items);
}
}
console.log(thCount);
Object.values gives you the list of values of a given object and then you can map your result in an array. in ES5:
var arr = Object.values(mydata.thsub).map(function(item) {
return item.stats.items
});
in ES6:
const list = Object.values(mydata.thsub).map(item => item.stats.items);
You could use an iterative recursive approach for getting the wanted values.
function getValues(object, key) {
function iter(o) {
if (key in o) {
result.push(o[key]);
}
Object.keys(o).forEach(function (k) {
if (o[k] && typeof o[k] === 'object') {
iter(o[k]);
}
});
}
var result = [];
iter(object);
return result;
}
var data = { id: "123", name: "name here", thsub: { 637: { id: "637", name: "Sub 1", stats: { items: 5, }, ons: null }, 638: { id: "638", name: "Sub 2", stats: { items: 10, }, ons: null } }, ph: 10, };
console.log(getValues(data, 'items'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Building new JSON from existing one

I want to build an new JSON from existing one. The source has sections and rubrics that I no longer need for a listing. The new object called 'items' should have an array of the items.
The final JSON should be sorted by attribute 'name' and look like
{
"items": [
{
"id": 10000006,
"name": "Boah"
},
{
"id": 10000013,
"name": "Gut"
},
{
"id": 10000003,
"name": "Ipsum"
},
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000002,
"name": "Stet"
}
]
}
For building the new JSON I get this source:
{
"sections": [
{
"name": "FooBar",
"rubrics": [
{
"name": "Foo",
"items": [
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000002,
"name": "Stet"
},
{
"id": 10000003,
"name": "Ipsum"
}
]
},
{
"name": "Bar",
"items": [
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000006,
"name": "Boah"
}
]
}
]
},
{
"name": "BlahBloob",
"rubrics": [
{
"name": "Bla",
"items": [
{
"id": 10000013,
"name": "Gut"
}
]
},
{
"name": "Bloob",
"items": [
{
"id": 10000014,
"name": "Name"
},
{
"id": 10000015,
"name": "Lorem"
}
]
}
]
}
]
}
What do you think? How can I do this with plain JavaScript or maybe TypeScript?
Thanks for reading and have time for my question. And thanks for reply in advance.
Here you go. You just need to iterate over each rubric of each section of your source to get the items. At the end, sort your list of items by items, and you're done.
This example uses ES6 syntax, but it's easy to convert it to ES5 if needed.
function extractItems(source) {
const items = [];
for (const section of source.sections) {
for (const rubric of section.rubrics) {
items.push(...rubric.items);
}
}
items.sort((a, b) => a.name.localeCompare(b.name));
return { items };
}
A more functional approach use map and reduce to pick the rubrics and merge them.
data.sections
.map(section => section.rubrics) // get rubrics
.reduce((a, b) => a.concat(b)) // merge rubrics
.map(rubric => rubric.items) // get items from each rubric
.reduce((a, b) => a.concat(b)) // merge items
.sort((a, b) => a.name.localeCompare(b.name)); // sort
function(oldObj) {
var newObj = {
"items": []
};
oldObj.sections.forEach(function(section) {
section.rubrics.forEach(function(rubric) {
rubric.items.forEach(function(item) {
newObj.items.push(item);
});
});
});
newObj.items = newObj.items.sort(function(a, b) {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return newObj;
}
And simply use JSON.parse() and JSON.stringify() to convert JSON to and from objects.
It might help you
var data ={
"sections": [
{
"name": "FooBar",
"rubrics": [{"name": "Foo", "items": [{"id": 10000001,"name": "Lorem"}, {"id": 10000002,"name": "Stet"}, {"id": 10000003,"name": "Ipsum"}]
}, {
"name": "Bar",
"items": [{
"id": 10000004,
"name": "Name"
}, {
"id": 10000005,
"name": "Lorum"
}, {
"id": 10000006,
"name": "Boah"
}]
}]
}, {
"name": "BlahBloob",
"rubrics": [{
"name": "Bla",
"items": [{
"id": 10000013,
"name": "Gut"
}]
}, {
"name": "Bloob",
"items": [{
"id": 10000014,
"name": "Name"
}, {
"id": 10000015,
"name": "Lorem"
}]
}]
}]
};
var itemObj = {};
var itemArr = [];
var sections = data.sections;
for(var i=0;i<sections.length;i++)
{
for(var j=0;j<sections[i].rubrics.length;j++){
for(var k=0;k<sections[i].rubrics[j].items.length;k++){
var itemObj;
itemObj['id'] = sections[i].rubrics[j].items[k].id;
itemObj['name'] = sections[i].rubrics[j].items[k].name;
itemArr.push(itemObj);
}
}
}
var finalObj = {"items":itemArr};
console.log(finalObj);
JSFiddle

Categories

Resources