get the array index in swift [duplicate] - ios

This question already has answers here:
How to find index of list item in Swift?
(23 answers)
Closed 7 years ago.
Here is my code in Swift for an iOS app.
class Test {
var name: String
var sname: String
init(name: String, sname: String) {
self.name = name
self.sname = sname
}
}
class ArrTest {
var arr = [Test]()
init() {
arr.append(Test(name: "test1", sname: "surname1"))
arr.append(Test(name: "test2", sname: "surname2"))
arr.append(Test(name: "test3", sname: "surname3"))
arr.append(Test(name: "test4", sname: "surname4"))
}
}
var x = ArrTest()
let obj = x.arr.filter { $0.name == "test1" }.first
println(obj?.sname)
I want to get the index and not the object of the first array object (in the array var). The "obj" x.arr.filter... returns the first object. I need the index of the correct object.

Well you can simply use the method find of the array:
// This is pseudocode haven't tried it but should go along those lines.
var x = ArrTest()
var searchMe = Test("test1", "surname1");
let obj = find(x, searchMe);
For this to work you need to implement the Equatable protocol, here you can find a simple tutorial. After that find should work with your test class.
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d")

Related

Array of objects from multiple loops [duplicate]

This question already has answers here:
How can I run through three separate arrays in the same for loop?
(6 answers)
Closed 4 years ago.
I would like to end up with an array of custom objects. I'm having trouble figuring out a way to go about this when I have multiple arrays to iterate through in order to create the custom objects. I have something like this:
class CustomObject {
var name = ""
var place = ""
var price = ""
}
var nameArray = [“name1”,"name2","name3"]
var placeArray = [“place1”,"place2","place3"]
var priceArray [“price1”,"price2","price3"]
var customArray [CustomObject]()
createObject(name : nameArray, place : placeArray, price : priceArray)
func createObject(name : [String], place : [String], price : [String]) {
let instance = CustomObject()
for names in name {
instance.name = names
}
for places in place {
instance.place = places
}
for prices in price {
instance.price = prices
customArray.append(instance)
}
}
I would like to end up with an array of those custom "instances". Right now my code is giving each attribute the last index of each array.
You can try , also i suppose all the arrays have the same count
var customArray = [CustomObject]()
for i in 0..<nameArray.count {
let instance = CustomObject()
instance.name = nameArray[i]
instance.place = placeArray[i]
instance.price = priceArray[i]
customArray.append(instance)
}

Cannot add an append an array into a dictionary that has an empty array

I have a Profile Data singleton class as follows.
I am trying to store data into an empty array in a dictionary .
After appending data to the array also the count of the array is 0.
class ProfileData{
static let sharedInstance = ProfileData()
var artistProfileDict = [String : Profile]()
var loggedInUserProfile = Profile(artistName: "John Smith", artistDescription: "Admiral of New England, English soldier, explorer, and author.", totalLikes: "174", totalViews: "200", totalFollowing: "100",totalFollowers:"50",imageUrl:"image_singer", feeds:[] )
private init() {
getProfilesDictionary()
}
func getProfilesDictionary()->[String: Profile]{
artistProfileDict["John Smith"] = loggedInUserProfile
return artistProfileDict
}
func add(array: Feed, artistName: String) {
artistProfileDict[artistName]!.feeds.append(array)
}
}
In another view Controller I am trying to add an array to the empty array in the dictionary as follows
let newFeed = Feed(profilePicture: "image",artistName: "New",
videoUrl: "url",videoTitle:"New", videoViews: "160",likes:
"200",shoutouts: "200",comments: [],votes: "50", dateCreated: Date(),
userActivity :"This user liked your video")
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
After appending the array to the empty array in the dictionary I still get the count of the array as 0.
I am not able to figure out the problem here. Any help will appreciated . Thank you.
Profile class
struct Profile {
var artistName: String
var artistDescription: String
var totalLikes: String
var totalViews: String
var totalFollowing: String
var totalFollowers: String
var imageUrl: String
var feeds : [Feed]
init(artistName: String,artistDescription:String,totalLikes:String,totalViews:String,totalFollowing:String,totalFollowers:String,imageUrl:String, feeds:[Feed]) {
self.artistName = artistName
self.artistDescription = artistDescription
self.totalLikes = totalLikes
self.totalViews = totalViews
self.totalFollowing = totalFollowing
self.totalFollowers = totalFollowers
self.imageUrl = imageUrl
self.feeds = feeds
}
}
It's working fine
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
ProfileData.sharedInstance.artistProfileDict["John Smith"]?.feeds.count // 1
Probably you are using wrong class ArtistProfileData instead of ProfileData.

Group elements with the same property value from an array [duplicate]

This question already has answers here:
How to group by the elements of an array in Swift
(16 answers)
Closed 6 years ago.
I have an array [modelA,modelB,modelC,modelD,modelE], each element in the array is an instance of a Struct. The Struct has a property "name". for example...
modelA.name = "abc"
modelB.name = "efg"
modelC.name = "hij"
modelD.name = "abc"
modelE.name = "efg"
How can I group elements with the same property value into a new array? i.e. put modelA and modelD into a new array,and put modelB and modelE into another array.
Assume the original array is large.
You can achieve this by using filter(_:):
Returns an array containing, in order, the elements of the sequence
that satisfy the given predicate.
For example, consider that the structure looks like:
struct Model {
var name: String?
}
And you have an array of models:
let allModelsArray = [Model(name: "abc"), Model(name: "efg"), Model(name: "hij"), Model(name: "abc"), Model(name: "efg"), Model(name: "efg"), Model(name: "hij")]
So, you can get your arrays by doing (assuming that you want to filter based on the value of the name):
let abcModelsArray = allModelsArray.filter { $0.name == "abc" }
// [Model(name: Optional("abc")), Model(name: Optional("abc"))]
let hijModelsArray = allModelsArray.filter { $0.name == "hij" }
// [Model(name: Optional("hij")), Model(name: Optional("hij"))]
ALSO:
You mentioned that:
how can I put element which has the same property value into a new
array, such as put modelA and modelD into a new array, and put modelB
and modelE into a new array, if array is large.
Somehow, you might want to use the lazy version of the collection.
Hope this helped.
I have not performance tested this
struct Model {
var type : String
var name : String
}
var modelA = Model(type: "A", name: "abc")
var modelB = Model(type: "B", name: "efg")
var modelC = Model(type: "C", name: "abc")
var modelD = Model(type: "D", name: "efg")
let models = [modelA,modelB,modelC,modelD]
let names = Set(models.map({return $0.name}))
var groupedModels : [String:[Model]] = [:]
for var name in names {
let elements = models.filter({$0.name == name})
groupedModels[name] = elements
}
.reduce solution:
let a = [modelA, modelB, modelC, modelD, modelE]
let arr = a.reduce([:]) { (result, currentModel) -> [String: [Model]] in
var mutableDic = result
if ((mutableDic[currentModel.name]) != nil) {
mutableDic[currentModel.name]?.append(currentModel)
} else {
mutableDic[currentModel.name] = [currentModel]
}
return mutableDic
}
It will return the same dictionary as #Grimxn response. or got from this for loop
var mutableDic = [String : [Model]]()
for aModel in a {
if ((mutableDic[aModel.name]) != nil) {
mutableDic[aModel.name]?.append(aModel)
} else {
mutableDic[aModel.name] = [aModel]
}
}
The key is to use a Dictionary to track for Model that need to be put in the same array, by comparing to it's .name.

Passing custom swift object to javascript methods as input

I'm using javascriptcore framework to interact with the JS file functions.
I have the object in the following type
class Test: NSObject {
var testId: NSNumber?
var testIndex: Int?
var testDate: NSDate?
var title: String?
var status: String?
}
I'm creating the array of object and passing as input to javascript method like below
var testArray = [Test]()
for i in 0 ..< 4 {
let test = Test()
test.testId = i * 3
test.testIndex = i
test.testDate = NSDate()
test.title = "Test \(i)"
test.status = "waiting"
testArray.append(test)
}
I have to pass this array to method to JS, Please let me know how to pass it.
You should be able to pass the attributes to JS as described here:
http://nshipster.com/javascriptcore/
The blocks-way
Couldn't test the code without Mac now, but is maybe working:
let testArrayCount: #convention(block) Void -> String = {
return testArray.count
}
let transferTest: #convention(block) String -> (String, String, String, String, String) = {
i in
return ( String(testArray[i].0),String(testArray[i].1),String(testArray[i].2),testArray[i].3,testArray[i].4 )
}
context.setObject(unsafeBitCast(testArrayCount, AnyObject.self), forKeyedSubscript: "testArrayCount")
context.setObject(unsafeBitCast(transferTest, AnyObject.self), forKeyedSubscript: "transferTest")
Now you can read the array in your JS-code (this is Pseudocode now):
var jsTestArray;
for ( i=0, i<testArrayCount(), i++ ) {
jsTestArray.append( transferTest(i) );
}
After loading object after object into your Javascript, you should be able to work with the array. If you don't want to work with strings only you may have to cast the things back (but as JS noob I don't wheather it's necessary)
Using JSExport Protocol
You can try it also the other way, described on http://nshipster.com/javascriptcore/ .
Hope, this answered your question?

How to find the index of an item in an array of class in Swift?

Well first of all we all know that finding an index of an array is easy but I got stump finding an index of an item in an array which contains multiple structs.
This is my class:
class Patient{
private var id: Int
private var name: String
private var gender: String
private var mileage: Double
//global variable
var globalPatientID:Int{
return id
}
var globalPatientName:String{
return name
}
var globalPatientGender:String{
return gender
}
var globalPatientMileAge:Double{
return mileage
}
init(id:Int, name:String, gender:String, mileage:Double){
self.id = id
self.name = name
self.gender = gender
self.mileage = mileage
}
}
This is my array:
let AppUserID = prefs.objectForKey("AppUserID")
for var i=0; i<nou; ++i{
numberOfUsersExisting = nou
if (AppUserID as? String == json[0][i]["App_ID"].stringValue){
print("Assigning AppUserID")
appUserMileage = json[0][i]["Mileage"].doubleValue
}
pSample += [Patient(id: json[0][i]["ID"].intValue, name: json[0][i]["Name"].stringValue, gender: json[0][i]["Gender"].stringValue, mileage: json[0][i]["Mileage"].doubleValue)]
pSample.sortInPlace({$0.globalPatientMileAge < $1.globalPatientMileAge})
}
So pSample is initially a blank array and it appends a class of items through a loop.
The sortInPlace function helps me to sort pSample based on globalPatientMilaAge.
So this got me thinking, how do I get the index of my AppUserID(which I cast it as a String) from the array of class?
I tried using this function but it doesn't seems working because I'm looping through classes instead of items inside a class.
appUserRanking = pSample.indexOf("\(AppUserID)")
The body of indexOf can be a closure like the map and filter functions
appUserRanking = pSample.indexOf{$0.globalPatientID == AppUserID}
PS: It's pretty inefficient to get one object from json (json[0][i]) 6 times in the repeat loop.
Assign the object to a variable
let object = json[0][i]
and use it for example
if (AppUserID as? String == object["App_ID"].stringValue){
Do like this,
let pSampleFiltered = pSample.filter {$0.globalPatientID == AppUserID}
if pSampleFiltered.count > 0 {
if let index = pSample.indexOf(pSampleFiltered.first!) {
// Do your stuff here
}
}
In Swift 3 and above mapping works like this
appUserRanking = pSample.index(where: {$0.globalPatientID == AppUserID})

Resources