I have a contoroller:
$scope.getFromDB=function(data)
{
$scope.nameSelected=[];
var myCookie=$cookie.get("nameCookie");
$scope.names= data;
for(var i=0; i<$scope.names.length;i++)
{
if($scope.names._id=myCookie._id)
{
$scope.nameSelected.push($scope.names[i]);
}
}
I want display the user's firstname, middlename, lastname stored in the $scope.nameSelected, since the nameSelectedis in the array form, name are got in array nameSelected[0].firstname, nameSelected[0].middlename,nameSelected[0].lastname. So how to convert it into a object so it is easy to access the names.
From what you've written,you don't need an array at all, just use an object.
Change this:
$scope.nameSelected=[];
...
$scope.nameSelected.push($scope.names[i]);
to
$scope.nameSelected = null;
...
$scope.nameSelected = $scope.names[i];
Based on what you've mentioned in your question, it is already an object at the index 0 of your nameselected array, That means, doing,
$scope.nameselected[0]
should give you this,
{firstName : "Robert", middlename :"Downy", lastName:"junior"}
Similarly, for all the names as in your loop ,
$scope.nameselected = $scope.names[i]
Related
I have a struct and an array of my structs as follows
struct Products{
var ProductType: String
var ProductName: String
var ProductLink: String
}
var CleaningProductsArray = [Products]()
When I write to my array of structs the ProductName Variable inside it sometimes can be written by the user with trailing whitespaces. I would like to return a version of the CleaningProductsArray but with all instances of ProductName having any trailing whitespaces removed. I have been trying to achieve with map as below but does not return what I would like it to. What is the most efficient way to do this?
let trimmed = CleaningProductsArray.map{ $0.ProductName.trimmingCharacters(in: .whitespaces) }
Quick answer is:
let trimmed: [Products] = CleaningProductsArray.map { product in
var adjusted = product
adjusted.ProductName = product.ProductName.trimmingCharacters(in: .whitespaces)
return adjusted
}
As it was correctly mentioned in the comments, there are things you can improve in your overall code design.
You could start with converting your model to meet Swift naming standards, which means not using plural for Products since the objects of this type describe a single product, and removing the product prefix from properties since its obvious from the context that they describe a "Product". Ideally you would also make the properties immutable, to make passing them around safer (google "Benefits of immutability"). You should create some other object responsible for collecting all the data for your product objects.
struct Product {
let type: String
let name: String
let link: String
}
Also, you should never use uppercased names for your variables/constants/properties/functions in Swift, so it's best to replace the CleaningProductsArray with cleaningProductsArray for the sake of readability. Uppercased names are reserved for types. Also you might want to drop the Array suffix since it's obvious from the type that it is an array
var cleaningProducts = [Product]()
let trimmed: [Product] = cleaningProducts.map {
Product(
type: $0.type,
name: $0.name.trimmingCharacters(in: .whitespaces),
link: $0.link
)
}
I want to sort an Array of objects, by the properties it shares with another Array of objects
struct GeneralComposition : Decodable {
let id, formId, relationId, fixedContentTypeId, separatorId: Int
let orderBy: Int
}
struct FixedContentType: Decodable {
let name, htmlType: String
let isEditable: Int
let typeId : String
}
var fixedContentType = [FixedContentType]()
var generalComposition = [GeneralComposition]()
In GeneralComposition I get the order the items must have, with orderBy, and then take every item's fixedContentTypeID, compare with the typeId in FixedContentType to get the order in which this content must be showed in screen.
Any idea about how can it be done?
Thanks!
You can build a dictionary for the fixedContentTypeID’s of generalComposition:
let order = generalComposition.reduce(into: [Int: Int]()) { result, value in
result[value.fixedContentTypeId] = value.orderBy
}
You now have an efficient way to lookup the orderBy value for a given typeId within your array of FixedContentType objects. You can use that for sorting:
fixedContentType.sort {
(order[$0.typeId] ?? 0) < (order[$1.typeId] ?? 0)
}
By the way, your typeId is a String, and fixedContentTypeId is an Int. I’m assumed that was a typo introduced when preparing the question, and that they’re really both Int. If they’re really different types (which would be weird), the solution would be similar, though you’d have to do some conversions. But I didn’t want to go there unless you confirmed that this is really what you model was.
But, given that your typeId really is a String, you could make your dictionary a [String: Int]:
let order = generalComposition.reduce(into: [String: Int]()) { result, value in
result[String(value.fixedContentTypeId)] = value.orderBy
}
So, I get some JSON values from the server but I don't know if there will be a particular field or not.
So like:
{ "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited"
}
And sometimes, there will be an extra field like:
{ "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited",
"club":"somevalue"
}
I would like to check if the field named "club" exists so that at parsing I won't get
org.json.JSONException: No value for club
JSONObject class has a method named "has":
http://developer.android.com/reference/org/json/JSONObject.html#has(java.lang.String)
Returns true if this object has a mapping for name. The mapping may be NULL.
You can check this way where 'HAS' - Returns true if this object has a mapping for name. The mapping may be NULL.
if (json.has("status")) {
String status = json.getString("status"));
}
if (json.has("club")) {
String club = json.getString("club"));
}
You can also check using 'isNull' - Returns true if this object has no
mapping for name or if it has a mapping whose value is NULL.
if (!json.isNull("club"))
String club = json.getString("club"));
you could JSONObject#has, providing the key as input and check if the method returns true or false. You could also
use optString instead of getString:
Returns the value mapped by name if it exists, coercing it if
necessary. Returns the empty string if no such mapping exists
just before read key check it like before read
JSONObject json_obj=new JSONObject(yourjsonstr);
if(!json_obj.isNull("club"))
{
//it's contain value to be read operation
}
else
{
//it's not contain key club or isnull so do this operation here
}
isNull function definition
Returns true if this object has no mapping for name or
if it has a mapping whose value is NULL.
official documentation below link for isNull function
http://developer.android.com/reference/org/json/JSONObject.html#isNull(java.lang.String)
You can use has
public boolean has(String key)
Determine if the JSONObject contains a specific key.
Example
JSONObject JsonObj = new JSONObject(Your_API_STRING); //JSONObject is an unordered collection of name/value pairs
if (JsonObj.has("address")) {
//Checking address Key Present or not
String get_address = JsonObj .getString("address"); // Present Key
}
else {
//Do Your Staff
}
A better way, instead of using a conditional like:
if (json.has("club")) {
String club = json.getString("club"));
}
is to simply use the existing method optString(), like this:
String club = json.optString("club);
the optString("key") method will return an empty String if the key does not exist and won't, therefore, throw you an exception.
Try this:
let json=yourJson
if(json.hasOwnProperty(yourKey)){
value=json[yourKey]
}
Json has a method called containsKey().
You can use it to check if a certain key is contained in the Json set.
File jsonInputFile = new File("jsonFile.json");
InputStream is = new FileInputStream(jsonInputFile);
JsonReader reader = Json.createReader(is);
JsonObject frameObj = reader.readObject();
reader.close();
if frameObj.containsKey("person") {
//Do stuff
}
Try this
if(!jsonObj.isNull("club")){
jsonObj.getString("club");
}
I used hasOwnProperty('club')
var myobj = { "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited"
};
if ( myobj.hasOwnProperty("club"))
// do something with club (will be false with above data)
var data = myobj.club;
if ( myobj.hasOwnProperty("status"))
// do something with the status field. (will be true with above ..)
var data = myobj.status;
works in all current browsers.
You can try this to check wether the key exists or not:
JSONObject object = new JSONObject(jsonfile);
if (object.containskey("key")) {
object.get("key");
//etc. etc.
}
I am just adding another thing, In case you just want to check whether anything is created in JSONObject or not you can use length(), because by default when JSONObject is initialized and no key is inserted, it just has empty braces {} and using has(String key) doesn't make any sense.
So you can directly write if (jsonObject.length() > 0) and do your things.
Happy learning!
You can use the JsonNode#hasNonNull(String fieldName), it mix the has method and the verification if it is a null value or not
i have a struct array that i want "break up" into smaller arrays that can be called as needed or at least figure out how i can map the items needed off one text value.
the struct:
struct CollectionStruct {
var name : String
var description : String
var title : String
var image : PFFile
var id: String
}
and the array made from the struct
var collectionArray = [CollectionStruct]()
var i = 0
for item in collectionArray {
print(collectionArray[i].name)
i += 1
}
printing partArray[i].name gives the following result:
pk00_pt01
pk00_pt02
pk00_pt03
pk01_pt01
pk01_pt02
pk01_pt03
pk01_pt04
pk01_pt05
pk01_pt06
pk01_pt07
pk01_pt08
this is just some test values but there could be thousands of entries here so i wanted to filter the entire array just by the first 4 characters of [i].name i can achieve this by looping through as above but is this achievable using something like .map?
I wanted to filter the entire array just by the first 4 characters of
[i].name
You can achieve this by filtering the array based on the substring value of the name, as follows:
let filteredArray = collectionArray.filter {
$0.name.substring(to: $0.name.index($0.name.startIndex, offsetBy: 4)).lowercased() == "pk00"
// or instead of "pk00", add the first 4 characters you want to compare
}
filteredArray will be filled based on what is the compared string.
Hope this helped.
If you want to group all data automatically by their name prefix. You could use a reducer to generate a dictionary of grouped items. Something like this:
let groupedData = array.reduce([String: [String]]()) { (dictionary, myStruct) in
let grouper = myStruct.name.substring(to: myStruct.name.index(myStruct.name.startIndex, offsetBy: 4))
var newDictionart = dictionary
if let collectionStructs = newDictionart[grouper] {
newDictionart[grouper] = collectionStructs + [myStruct.name]
} else {
newDictionart[grouper] = [myStruct.name]
}
return newDictionart
}
This will produce a dictionary like this:
[
"pk00": ["pk00_pt01", "pk00_pt02", "pk00_pt03"],
"pk01": ["pk01_pt01", "pk01_pt02", "pk01_pt03", "pk01_pt04", "pk01_pt05", "pk01_pt06", "pk01_pt07"],
"pk02": ["pk02_pt08"]
]
Not sure if i am understanding you correctly but it sounds like you are looking for this...
To create a new array named partArray from an already existing array named collectionArray (that is of type CollectionStruct) you would do...
var partArray = collectionArray.map{$0.name}
I'm trying to create two spreadsheets: one tracks student attendance at school, the other tracks their attendance at Track practice. The goal is to write a function, that I can set up as a button, that I can click that will automatically send emails to several people if the student is present at school but is absent for sports without getting excused.
Right now, the whole thing is working pretty well, but I have one issue. I have a column that will read "Good" or "Bad" depending on whether the student meets the above condition. The function turns these into an array. I would like to use the index of the "Bad"'s to find the necessary email addresses, which are stored at the same index point in another array that I make from the spreadsheet. I'm not sure how to save this index point and use it to reference the email addresses. Code below.
function sendEmailsMonday() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TrackAttendance");
var dataRange = sheet.getRange("D2:D30");
var data = dataRange.getValues();// Gets array of "Good" and "Bad"
for (i in data) {
if(i = "Bad") {
var place = data.indexOf(i);
var dataRange2 = sheet.getRange("M2:M30");// Gets array of email addresses
var data2 = dataRange2.getValues();
var emailAddress = data2[place];
var message = "This is an automated email informing you that your child/advisee ____ was present at school today, but missed Track without being excused. Feel free to email Mr. # with any questions.";
var subject = "___ missed Track Practice";
MailApp.sendEmail(emailAddress, subject, message);
return;
}
}
}
So, the issue comes in with the index lines. If I get rid of
var place = data.indexOf(i);
and replace
var emailAddress = data[place];
with
var emailAddress = data[28];
or any other number, it will grab the email address and send it. But then it has nothing to do with the values in the other column.
Seems like this should be an easy fix but I'm bad at this.
Very late responding now. I think you are almost there.
Your IF statement should read:
if(i == "Bad") {
And then replace 'place' with i:
var emailAddress = data2[i];
It should work as expected now.