I am using AngularJS. I have a json object as below;
info = [
{
"name": "Tom",
"id": "111"
},
{
"name": "Sam",
"id": "222"
},
{
"name": "James",
"id": "333"
}
]
I want to have a function such that when a matching name is found, some action is taken (in this -case, return the corresponding id.) In other words, if the input matching name is 'Tom', I want to return the id '111' based on the json object above.
I wrote some code to find a matching name.
$scope.getIdFromName = function()
{
angular.forEach(info, function(value, key)
{
//$scope.searchByName contains the name to be matched
if (key === 'name' && value === $scope.searchByName)
{
//$scope.searchById is the id to be returned
$scope.searchById = key;
alert("found");
}
});
};
Where did the code go wrong? Or is it so wrong that it is better to be completely rewritten? Any suggestions (does not need to be angularjs) will be most welcome. Thank you very much.
Since info is an array of objects, the key is going to be the index of each item, and value will be the whole object at that index. Your forEach should look like this:
angular.forEach(info, function(value, key)
{
//$scope.searchByName contains the name to be matched
if (value.name === $scope.searchByName)
{
//$scope.searchById is the id to be returned
$scope.searchById = value.id;
alert("found");
}
});
Related
I am trying to filter a JavaScript array (JSON array) with the string array, and set it back in itself.
I am using this code (Removed JSON.stringiFy from allRecords,it was just to show the records on console)
var statusFilters = component.get("v.statusFilters");
console.log('statusFilters--->'+statusFilters);
var allRecords = component.get("v.empWrapperList");
console.log('allRecords--->'+allRecords);
var filteredRecords = allRecords.filter(rec => rec.Status__c == statusFilters);
console.log(filteredRecords);
component.set("v.empWrapperList",filteredRecords);`
Here statusFilter is a string array and allRecords is an object array.
Here are the logs from console.
statusFilters--->Paid
ClaimsDemo.js:119 allRecords--->
[
{
"Id": "a1V2x000001K29pEAC",
"Name": "CL-0000004",
"Member__c": "0032x000004bgAkAAI",
"Date_of_Service__c": "2020-06-25",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Void"
},
{
"Id": "a1V2x000001K14OEAS",
"Name": "CL-0000003",
"Member__c": "0032x000004bgAkAAI",
"Billed__c": 22,
"Date_of_Service__c": "2015-09-15",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Denied"
},
{
"Id": "a1V2x000001K14JEAS",
"Name": "CL-0000002",
"Member__c": "0032x000004bgAkAAI",
"Billed__c": 22,
"Date_of_Service__c": "2019-10-16",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Rejected"
},
{
"Id": "a1V2x000001K14EEAS",
"Name": "CL-0000001",
"Member__c": "0032x000004bgAkAAI",
"Billed__c": 22,
"Date_of_Service__c": "2020-06-04",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Paid"
}
]
Actually it is unable to execute this line
var filteredRecords = allRecords.filter(rec => rec.Status__c == statusFilters);
Can you please help.
your first problem is stringifying.filter method is for array.
second problem is that you cant say rec.Status__c === statusFilters statusFiltersis array and Status__c is string. map to array your object array with correct key name and search rec.Status__c in this array. indexOf is a method to find in array
if statusFilters is just array which includes types like
["Void","Denied"]
then
var filteredRecords = allRecords.filter(rec => statusFilters.indexOf(rec.Status__c)>-1);
if statusFilters is an object array like
[ {"Status__c": "Void" }];
then
var filteredRecords = allRecords.filter(rec => ( statusFilters.map(x=>x.Status__c)).indexOf(rec.Status__c)>-1);
I want to fetch all the names and label from JSON without loop. Is there a way to fetch with any filter method?
"sections": [
{
"id": "62ee1779",
"name": "Drinks",
"items": [
{
"id": "1902b625",
"name": "Cold Brew",
"optionSets": [
{
"id": "45f2a845-c83b-49c2-90ae-a227dfb7c513",
"label": "Choose a size",
},
{
"id": "af171c34-4ca8-4374-82bf-a418396e375c",
"label": "Additional Toppings",
},
],
},
]
}
When you say "without loops" I take it as without For Loops. because any kind of traversal of arrays, let alone nested traversal, involve iterating.
You can use the reduce method to have it done for you internally and give you the format you need.
Try this :
const data = {
sections: [
{
id: "62ee1779",
name: "Drinks",
items: [
{
id: "1902b625",
name: "Cold Brew",
optionSets: [
{
id: "45f2a845-c83b-49c2-90ae-a227dfb7c513",
label: "Choose a size"
},
{
id: "af171c34-4ca8-4374-82bf-a418396e375c",
label: "Additional Toppings"
}
]
}
]
}
]
};
x = data.sections.reduce((acc, ele) => {
acc.push(ele.name);
otherName = ele.items.reduce((acc2, elem2) => {
acc2.push(elem2.name);
label = elem2.optionSets.reduce((acc3, elem3) => {
acc3.push(elem3.label);
return acc3;
}, []);
return acc2.concat(label);
}, []);
return acc.concat(otherName);
}, []);
console.log(x);
Go ahead and press run snippet to see if this matches your desired output.
For More on info reduce method
In the context of cJSON
yes, we can fetch the key value for any of the object.
1 - each key value is pointed by one of the objects. will simply fetch that object and from there will get the key value.
In the above case for
pre-requisition: root must contain the json format and root must be the cJSON pointer. if not we can define it and use cJSON_Parse() to parse the json.
1st name object is "sections" will use
cJSON *test = cJSON_GetObjectItem(root, "sections");
char *name1 = cJSON_GetObjectItem(test, "name" )->valuestring;
2nd name key value
cJSON *test2 = cJSON_GetObjectItem(test, "items");
char *name2 = cJSON_GetObjectItem(tes2, "name")->valuestring;
likewise, we can do for others as well to fetch the key value.
I would like to be able to type in "Hammerhead" to call the "Hammerhead Shark" object without its full name. Is this possible and if so how?
I tried using array.indexOf(string) though it doesn't really seem to help since it requires an exact match such as typing "Hammerhead Shark"
JS:
const JSON = require('animals.json');
var animals = Object.keys(JSON);
if (animals.indexOf("Hammerhead")) {
console.log(JSON["Hammerhead"].name);
}
JSON:
{
"Hammerhead Shark": {
"name": "Shark",
"age": "300"
},
"Duck": {
"name": "Duck",
"age": "1000"
}
}
I expect the output to be "Shark" instead of undefined.
It seems you want to get access the value in object. By its partial name.
Get the entries of object using Object.entries()
Find the key which includes() the given partial key.
return the second element of the found entry.
const obj = { "Hammerhead Shark": { "name": "Shark", "age": "300" }, "Duck": { "name": "Duck", "age": "1000" } }
function getValueByPartialKey(obj,key){
return (Object.entries(obj).find(([k,v]) => k.includes(key)) || [])[1]
}
console.log(getValueByPartialKey(obj,"Hammerhead"))
You can use string.includes(word) to return the name that matches the string that you're searching for, along with Array.filter iterates over the values too, and returns the result(s) you want.
I am trying to use underscoreJs to manipulate a JavaScript object and having problems doing so.
Here is my example
var data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
};
var res = _(data).chain().
pluck('parent').
flatten().
findWhere(function(item){
item === "user_get"
}).
value();
console.log(res);
Using an element which is a part of data.parent.calls[] (example : "user_get") I would like to extract its parent object, i.e. data.parent[0].
I tried above but always get undefined. I appreciate any help on this.
One of the problems you're having is your use of _.pluck. If you execute _.pluck over an object, it'll go over the keys of the object trying to retrieve the property you specified as the second argument (in this case, 'parent'). 'label' is a string and 'parent' is an array so thus the array that you get as a result is [undefined, undefined]. The rest will then go wrong.
One solution could be as follows:
function findCallIndexInParent(call, parent) {
return _.chain(parent)
.pluck('resources')
.flatten()
.findIndex(function (obj) {
return _.contains(obj.calls, call);
})
.value();
}
function findCall(call, data) {
var parent = data.parent;
return parent[findCallIndexInParent(call, parent)];
}
console.log(findCall('user_get', data));
findCall is just a convenient method that will pass the parent property of data to findCallIndexInParent (that will retrieve the index where call is) and return the desired object with the parent array.
Lodash (a fork of underscore) provides a method to get the property of an object that would have come really handy in here (sadly, underscore doesn't have it).
The explanation of findCallIndexInParent is as follows:
Chain the parent list
pluck the resources array
As pluck maps, it returns a list of lists so a flatten is needed.
Find the index of the element which calls contains call
Return the value (the index) of the object that contains call within parent.
Here's the fiddle. Hope it helps.
This would seem to do the trick.
function findByCall(data, call) {
return _.find(data.parent, function(parent) { //From data.parent list, find an item that
return _.some(parent.resources, function(resource) {//has such parent.resource that it
return _.includes(resource.calls, call); //includes the searched resource.calls item
});
});
}
//Test
var data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
};
console.log(findByCall(data, 'user_get'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
If I understand correctly, you want to get the index of the element in the parent array which has any resource with the specified call.
data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
}
// find the index of a parent
const index = _.findIndex(data.parent, parent =>
// that has any (some) resources
_.some(parent.resources, resource =>
// that contains 'user_get' call in its calls list
_.contains(resource.calls, 'user_get')
)
)
console.log(index) // 0
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
If you want to find the actual parent object, use find instead of findIndex
If you want to find all parent objects matching this call, use filter instead of findIndex
I want to search all the elemetns of a Javascript object and replace every occurance of the text "???" with, say for example, "***".
An example of the JSON would be
{
"page-title": "Tasks",
"sections": [{
"section-heading": "Work",
"subsections": [{
"subsection-heading": "First",
"subsection-texts": [{
"text": "This is some text."
}]
}, {
"subsection-heading": "Second",
"subsection-texts": [{
"text": "This is some more text."
}, {
"text": "This is even more text ???."
}]
}, {
"subsection-heading": "Third ???",
"subsection-texts": [{
"text": "This is the last text."
}]
}]
}]
}
As you can see, the "???" text could be at different levels. So is there some way of searching and replacing every occurance of $???$ with "***"?
I am looking for a method that will check the actual JSON object elements, I do not want a method that stringifys the object and then uses regex. Can this be done efficiently?
You can iterate through all object properties or array items with map/reduce and replace all question marks for strings:
var data = { ... }
function replaceQuestionMarks(obj) {
if (Array.isArray(obj)) {
return obj.map(function(o) {
return replaceQuestionMarks(o);
})
} else if (typeof obj === 'object') {
return Object.keys(obj).reduce(function(r, key) {
r[key] = replaceQuestionMarks(obj[key]);
return r;
}, {})
} else if (typeof obj === 'string') {
return obj.replace('???', '***');
}
return obj;
}
var replaced = replaceQuestionMarks(data);
One approach would be to convert it to a string, replace the question marks with a regular expression and then parse back into an object:
var myObject = {...};
myObject = (JSON.parse(JSON.stringify(myObject).replace(/\?\?\?/gi, '***')));
This might not be the best way to do it in terms of performance but we'd need more details about what you are actually doing. This may be just as efficient as other ways of doing it. How big are the objects on which you need to do this?