Javascript - Finding in subarray by value from another array - javascript

I have two javascript objects:
var classroom = {
"number" : "1",
"student" : [
{
"number" : 1,
"items" : [
{
"key" : "00000000000000000000001C",
"date" : "2016-04-21T17:35:39.997Z"
}
]
},
{
"number" : 2,
"items" : [
{
"key" : "00000000000000000000001D",
"date" :"2016-04-21T17:35:39.812Z"
},
{
"key" : "00000000000000000000002N",
"date" :"2016-04-21T17:35:40.159Z"
},
{
"key" : "00000000000000000000002Ñ",
"date" :"2016-04-21T17:35:42.619Z"
}
]
}
],
}
AND
var items = [
{
"fields" : {
"tags" : [
{
"key" : "00000000000000000000001C",
"Batch" : "50",
"Bin" : "01",
"Tray" : "02"
},
{
"key" : "00000000000000000000002N",
"Batch" : "55",
"Bin" : "05",
"Tray" : "12"
},
{
"key" : "000000000000228510000032",
"Batch" : "12",
"Bin" : "12",
"Tray" : "01"
}
],
"Name" : "Rubber"
},
"_id" : "56d19b48faa37118109977c0"
},
{
"fields" : {
"tags" : [
{
"key" : "00000000000000000000001D",
"Batch" : "50",
"Bin" : "01",
"Tray" : "05"
},
{
"key" : "00000000000000000000002Ñ",
"Batch" : "52",
"Bin" : "07",
"Tray" : "02"
},
{
"key" : "221567010000000000000089",
"Batch" : "11",
"Bin" : "15",
"Tray" : "03"
}
],
"Name" : "Book"
},
"_id" : "56d19b48faa37118109977c1"
}
];
Ok, I need to create a function that goes through every item of every student in classroom variable. With each item, I need to find in the items array the object that has the exact same key in one of its tags.
My code is getting strange results...missmatching items...
var finalitems = [];
classroom.student.forEach( function (student){
student.items.forEach( function (obj){
items.forEach( function (theitem){
theitem.fields.tags.forEach( function (tag){
if (tag.key === obj.key) {
var newitem = theitem;
newitem.tag = obj;
finalitems.push(newitem);
}
});
});
});
});
I know that foreach is a kind of a pointer but I don't really understand why it is working strange and how it should be done.
Regards,

javascript variables only save object references, not the actual object in memory, so this line:
var newitem = theitem;
means newitem refers to the same object as theitem, NOT create a new object from theitem.
so
newitem.tag = obj;
is the same as
theitem.tag = obj;
Which means you're modifying the input objects, that's why you won't get the expected output.
To get the desired behavior you need to create a copy of theitem and assign that object to newitem variable:
var newitem = Object.create(theitem);

Maybe this helps with a lot more iterations.
var classroom = { "number": "1", "student": [{ "number": 1, "items": [{ "key": "00000000000000000000001C", "date": "2016-04-21T17:35:39.997Z" }] }, { "number": 2, "items": [{ "key": "00000000000000000000001D", "date": "2016-04-21T17:35:39.812Z" }, { "key": "00000000000000000000002N", "date": "2016-04-21T17:35:40.159Z" }, { "key": "00000000000000000000002Ñ", "date": "2016-04-21T17:35:42.619Z" }] }] },
items = [{ "fields": { "tags": [{ "key": "00000000000000000000001C", "Batch": "50", "Bin": "01", "Tray": "02" }, { "key": "00000000000000000000002N", "Batch": "55", "Bin": "05", "Tray": "12" }, { "key": "000000000000228510000032", "Batch": "12", "Bin": "12", "Tray": "01" }], "Name": "Rubber" }, "_id": "56d19b48faa37118109977c0" }, { "fields": { "tags": [{ "key": "00000000000000000000001D", "Batch": "50", "Bin": "01", "Tray": "05" }, { "key": "00000000000000000000002Ñ", "Batch": "52", "Bin": "07", "Tray": "02" }, { "key": "221567010000000000000089", "Batch": "11", "Bin": "15", "Tray": "03" }], "Name": "Book" }, "_id": "56d19b48faa37118109977c1" }],
finalitems = [];
classroom.student.forEach(function (student) {
student.items.forEach(function (studentItem) {
items.forEach(function (item) {
item.fields.tags.forEach(function (itemTag) {
if (itemTag.key === studentItem.key) {
finalitems.push({
key: studentItem.key,
date: studentItem.date,
Batch: itemTag.Batch,
Bin: itemTag.Bin,
Tray: itemTag.Tray,
});
}
});
});
});
});
document.write('<pre>' + JSON.stringify(finalitems, 0, 4) + '</pre>');

Related

Search inside a JSON Javascript

I have a problem concern search JSON string and i have JSON string
{"userDetail":[
{
"Name": "Scottic Mangry",
"Age" : "12",
},
{
"Name": "Joneson Mangly",
"Age" : "18",
},
{
"Name": "Saoyu Wang",
"Age" : "15",
},
]}
And data search
let searchObj = "Mang"
I need a result
{
"Name": "Scottic Mangry",
"Age" : "12",
},
{
"Name": "Joneson Mangly",
"Age" : "18",
}
Any help or suggestions would be great!
Something like:
let data = {
"userDetail":[
{
"Name": "Scottic Mangry",
"Age" : "12",
},
{
"Name": "Joneson Mangly",
"Age" : "18",
},
{
"Name": "Saoyu Wang",
"Age" : "15",
},
]
}
let needle = "Mang";
let result = data['userDetail'].filter(el => el.Name.includes(needle));
console.log(result);
needle is the string we are searching for inside the Name property of the data.userDetail object
includes is case sensitive, so if you want to match results regardless of case it's easiest to lowercase everything first
you can do it using Array.filter, Array.values and includes
const data = {"userDetail":[
{
"Name": "Scottic Mangry",
"Age" : "12",
},
{
"Name": "Joneson Mangly",
"Age" : "18",
},
{
"Name": "Saoyu Wang",
"Age" : "15",
},
]}
const search = (data, search) => data.filter(d => Object.values(d).some(v => v.includes(search)))
console.log(search(data.userDetail, "Mang"))
As cmgchess say in comments
Using filter and includes would do the job for you:
to make it more declarative and readable I put it inside a function called findName
const objs = {
"userDetail": [{
"Name": "Scottic Mangry",
"Age": "12",
},
{
"Name": "Joneson Mangly",
"Age": "18",
},
{
"Name": "Saoyu Wang",
"Age": "15",
},
]
}
function findName(name) {
return objs.userDetail.filter(user => user.Name.includes(name))
}
let searchObj = "Mang";
console.log(findName(searchObj));
Just a simple filter.
({"userDetail":[
{
"Name": "Scottic Mangry",
"Age" : "12",
},
{
"Name": "Joneson Mangly",
"Age" : "18",
},
{
"Name": "Saoyu Wang",
"Age" : "15",
},
]}).userDetail.filter(e=>e.Name.includes("Mang"))

How to get the corresponding value from two objects

I have first data object which has a list of cafe, and second data object which has a list of cafe types.
I need find, get and display the corresponding type value from first data object and ID value from second data object.
For example: in list of cafe, I have Pinta with "type" : "3", it means that 3 is Bar from second object.
First object:
{
"list": {
"item": [
{
"ID": "31",
"name": "Staut",
"type": "1",
},
{
"ID": "34",
"name": "Pinta",
"type": "3",
}
]
}
}
And second object:
{
"list": {
"item": [
{
"ID": "1",
"name": "Restaurant",
},
{
"ID": "2",
"name": "Cafe",
},
{
"ID": "3",
"name": "Bar",
}
]
}
}
I can do it with Lodash. It is right, but I can't display it and it uses high memory.
getValues: function() {
_.forEach(CafeJSON.list.item, function(cafeValue) {
_.forEach(TypeJSON.list.item, function(typeValue){
if (cafeValue.type == typeValue.ID) {
console.log("Cafe name is: ", cafeValue.name, "and type is: ", typeValue.name)
}
})
})
}
Result:
I'd simplify the types object down to a object having key value pairs in the form of '3': 'Bar', then loop the items once, overriding the type property's value.
let list = {
"list": {
"item": [{
"ID": "31",
"name": "Staut",
"type": "1",
},
{
"ID": "34",
"name": "Pinta",
"type": "3",
}
]
}
}
let types = {
"list": {
"item": [{
"ID": "1",
"name": "Restaurant",
},
{
"ID": "2",
"name": "Cafe",
},
{
"ID": "3",
"name": "Bar",
}
]
}
}
let typesSimplified = types.list.item.reduce((a, b) => {
a[b.ID] = b.name;
return a;
}, {});
list.list.item.forEach(e => {
e.type = typesSimplified[e.type];
});
console.log(list);

Filter method on multidimensional array

I have an id and i to filter a multidimensional array with these. My code is:
service.fakedata.map(f=>{
f.results.map(r=>{
r = r.filter(m=> m.rId !== id)
})
})
and my array is :
"services": [
{
"id": "1839f72e-fa73-47de-b119-49fb971a5730",
"name": "In I/O Route",
"url": "http://wwww.in.io/[param1]/[param2]",
"inputParams": [
{
"id": "e74a6229-4c08-43a1-961f-abeb887fa90e",
"name": "in1",
"datatype": "string"
},
{
"id": "e74a6229-4c08-43a1-961f-abeb887fa90o",
"name": "in2",
"datatype": "string"
}
],
"isArrayResult": false,
"results": [
{
"id": "ef7c98db-9f12-45a8-b3fb-7d09a82abe3d",
"name": "out1",
"datatype": "string",
"fakedatatype": [
"address",
"city"
]
},
{
"id": "9b178ded-af27-43df-920f-daab5ad439b9",
"name": "out2",
"datatype": "string",
"fakedatatype": [
"internet",
"url"
]
}
],
"routeParameters": [
"param1",
"param2"
],
"fakedata": [
{
"id": "b0376694-9612-43d2-93ed-c74264df962e",
"url": "http://wwww.in.io/wood/good",
"params": [
{
"key": "param1",
"value": "wood"
},
{
"key": "param2",
"value": "good"
}
],
"inputParams": [
{
"iId":"e74a6229-4c08-43a1-961f-abeb887fa90e",
"key": "in1",
"value": "m"
},
{
"iId":"e74a6229-4c08-43a1-961f-abeb887fa90o",
"key": "in2",
"value": "z"
}
],
"results": [
{
"rId": "ef7c98db-9f12-45a8-b3fb-7d09a82abe3d",
"key": "out1",
"value": "result1",
"fakedatatype": [
"address",
"city"
]
},
{
"rId": "9b178ded-af27-43df-920f-daab5ad439b9",
"key": "out2",
"value": "result2",
"fakedatatype": [
"internet",
"url"
]
}
]
}
]
}
]
In this case filter is working (when I check with console.log) but it doesn't change fakedata array.
What was wrong with my code?
From https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
base on #H77 suggestion i change my code and now my code is look like this and everything work well
const s = service.fakedata.map(f=>{
f.results = f.results.map(r=>{
return r.filter(m=> m.rId !== id)
})
})

AngularJS adding and pushing in nested JSON objects

I have a JSON Object like this :
{
"Name": "Shivansh",
"RollNo": "1",
"Stream": "CSE",
"OverallScore": "76",
"Semester": [
{
"SemesterName": "FY-2012 - 1",
"TotalScore": "78.00",
"StartDate" : "2012-02-14",
"EndDate" : "2012-07-16",
"Amount" : "55000",
"Subject": [
{
"subjectname": "maths",
"score": "81"
},
{
"subjectname": "chemistry",
"score": "79"
},
{
"subjectname": "physics",
"score": "77"
}
]
},
{
"SemesterName": "FY-2013-1",
"TotalScore": "76.00",
"StartDate" : "2013-02-16",
"EndDate" : "2014-07-16",
"Amount" : "55000",
"Subject": [
{
"subjectname": "ADA",
"score": "80"
},
{
"subjectname": "Operating System",
"score": "77"
},
{
"subjectname": "Databases",
"score": "73"
},
{
"subjectname": "Economics",
"score": "71"
}
]
}
]
}
Now i want to add another semester field into this JSON by using angularJS. Can anyone help me how to achieve this. The next field that I would add may look like:
{
"SemesterName": "FY-2013-2",
"TotalScore": "75.00",
"StartDate" : "2011-02-16",
"EndDate" : "2012-07-16",
"Amount" : "55067800",
"Subject": [
{
"subjectname": "Sets and Probability",
"score": "78"
},
{
"subjectname": "Networking and Security",
"score": "76"
},
{
"subjectname": "Advanced DataBases",
"score": "72"
},
{
"subjectname": "Economics-2",
"score": "70"
}
]
}
so far I am using this type of controllers as mentioned below:
$scope.addRowSubject = function() {
$scope.insertsub = {
//id = $scope.getSubject.length+1;
subjectname : '1',
score : '1'
};
$scope.getSubject.push($scope.insertsub);
};
getSubject is the list of subjects which are present in one semester field. I am able to get this list without any issues.
$scope.addRowSemester = function() {
$scope.insertsem = {
//id = $scope.getSemester.length+1;
StartDate : "1",
EndDate : "1",
Amount : "1",
SemesterName : "1",
TotalScore : "1",
Subject : ""
}
$scope.getSemester.push($scope.insertsem);
};
getSemester is the list of Semesters in a Student.
I am able to push a semester field inside my JSON but as the Subject field is null i am not able to push the subject field. I hope you are getting the idea.
So any suggestions about this..
Thanks in advance.
Subject properties of your jsonObject is should be an instance of array, like this:
$scope.addRowSemester = function() {
$scope.insertsem = {
//id = $scope.getSemester.length+1;
StartDate : "1",
EndDate : "1",
Amount : "1",
SemesterName : "1",
TotalScore : "1",
Subject : []
}

How to query a json file?

Here is the file I would like to parse
I receive a file from a webservice in JSON format.
I would like to parse the content in such a way that I display the name of the president from the USA
{
"response": {
"result": {
"Countries": {
"row": [
{
"no": "1",
"FL": [
{
"content": "USA",
"val": "Country"
},
{
"content": "Barack Obama",
"val": "President"
}
]
},
{
"no": "2",
"FL": [
{
"content": "Cuba",
"val": "Country"
},
{
"content": "Raul Castro",
"val": "President"
}
]
}
]
}
}
}
}
The expected output
{ presidents: [
{ "name": "Barack Obama"}
]
}
could you provide a solution using a kind of JSON XPath?
Assuming that you are loading the response into a variable data:
var data = {
"response" : {
"result" : {
"Countries" : {
"row" : [{
"no" : "1",
"FL" : [{
"content" : "USA",
"val" : "Country"
}, {
"content" : "Barack Obama",
"val" : "President"
}
]
}, {
"no" : "2",
"FL" : [{
"content" : "Cuba",
"val" : "Country"
}, {
"content" : "Raul Castro",
"val" : "President"
}
]
}
]
}
}
}
};
You can then filter your data like this:
data.response.result.Countries.row.filter(function (el) {
return (el.FL[0].content == "USA");
})[0].FL[1];
To get to:
{
"content" : "Barack Obama",
"val" : "President"
}
To get the name, simply specify "content"
data.response.result.Countries.row.filter(function(el){
return (el.FL[0].content == "USA");
})[0].FL[1].content;
EDIT 1
One could search a json object like a string.
If we know that the element will have no children, then we could use something like this:
function find(query,obj) {
var str = JSON.stringify(obj);
var start = str.substr(0,str.indexOf(query)).lastIndexOf('{');
var end = str.substr(start,str.length).indexOf('}');
return str.substr(start,end);
}
console.log(find('"content":"USA"',data))
Despite of the age of the question I want to add this answer as reference for future visitors with the same problem:
You can use JSONPath. The page contains a description and an implementation in JavaScript and PHP.
t = {
"response": {
"result": {
"Countries": {
"row": [
{
"no": "1",
"FL": [
{
"content": "USA",
"val": "Country"
},
{
"content": "Barack Obama",
"val": "President"
}
]
},
{
"no": "2",
"FL": [
{
"content": "Cuba",
"val": "Country"
},
{
"content": "Raul Castro",
"val": "President"
}
]
}
]
}
}
}
}
res={};//Here we will store result
for (i in t.response.result.Countries.row) {
// get current country
country = t.response.result.Countries.row[i].FL[0].content;
// get current president
president = t.response.result.Countries.row[i].FL[1].content;
if (country == 'USA') {
res.presidents=[{name:president}];
break;
}
}

Categories