3

I have a protocol like this:

protocol Datable {
    var date: NSDate { get set }
}

struct DEPref: Datable {
   var date: NSDate
}

struct DEPObs: Datable {
   var date: NSDate
}

func fetchDepRefs() -> [DEPRef] {...}
func fetchDepObss() -> [DEPObs] {...}

I would like to create an array of DEPref and DEPObs in order to sort the final list.

I have tried many things but the compiler complains. Example:

var depRefList: Array<Datable> = fetchDepRefs()
var depObsList: Array<Datable> = fetchDepObss()
var allDeps = ...

An error in the first line "Cannot convert value of type [DEPref] to specified type Array"

2
  • 1
    See this Q&A for more info about why that type conversion fails. Commented Aug 15, 2016 at 7:43
  • If you feel an answer solved the problem, please mark it as 'accepted' by clicking the green check mark. This helps keep the focus on older SO which still don't have answers. Commented Aug 18, 2016 at 0:45

3 Answers 3

3

I'm very new to Swift/iOS programming, but something like this works for me.

func fetchDepRefs() -> Array<Datable> {return Array<Datable>()}

var depRefList = fetchDepRefs()
var testDEPref = DEPref(date: NSDate())
var testDEPref2 = DEPref(date: NSDate())

depRefList.append(testDEPref)
depRefList.append(testDEPref2)

for ref in depRefList {
    print(ref.date)
}

Your functions could also return [Datable]

eg.

func fetchDepRefs() -> [Datable] {return [Datable]()}

This also works for your scenario

Edit:

Or if you're looking for type safety in your functions, the following code will also work

func fetchDepRefs() -> [DEPref] {return [DEPref]()}
func fetchDepObss() -> [DEPObs] {return [DEPObs]()}

var depRefList = fetchDepRefs()
var depObsList = fetchDepObss()

var allDeps: [Datable] = [Datable]()

In this you can add elements from depRefList and depObsList to allDeps and everything will work fine.

Edit again:

This is a fully working example of what you're trying to achieve. In this I'm using the map function to transform the elements of the given arrays to Datable objects

protocol Datable {
    var date: NSDate { get set }
}

struct DEPref: Datable {
   var date: NSDate
}

struct DEPObs: Datable {
   var date: NSDate
}

func fetchDepRefs() -> [DEPref] {return [DEPref]()}
func fetchDepObs() -> [DEPObs] {return [DEPObs]()}

var depRefs = fetchDepRefs()
var depObs = fetchDepObs()

var ref1 = DEPref(date: NSDate())
var obs1 = DEPObs(date: NSDate())

depRefs.append(ref1)
depObs.append(obs1)

var allDeps = depRefs.map{$0 as Datable} + depObs.map{$0 as Datable}


for x in allDeps {
    print("I'm in allDeps array: \(x.date)")
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your answer, but i would like to keep my functions "fetchs" with the specific return type and not return the protocol. How you can merge the two arrays depRefList and depObsList ?
If you see my latest edit I've done exactly that. :)
My goal is to merge the two arrays and then sort the final array by date
There are other stackoverflow questions re. merging Swift arrays. The code I've given you allows you to create an array of Datable objects, that you can use to merge both DEPref and DEPObs arrays. See here for merging the contents of two arrays: stackoverflow.com/questions/25146382/…
Do you tried to merge the two arrays before posting the response ?
|
2

Are you running Swift 2 on iOS? The following runs successfully on Swift 3.

   http://swiftlang.ng.bluemix.net/#/repl/57b13a01133614f70db3347e

protocol Datable {
    var date: NSDate { get set }
}

struct Type1: Datable {
   var date: NSDate
}

struct Type2: Datable {
   var date: NSDate
}

var x : Datable = Type1(date:NSDate())
var y : Datable = Type2(date:NSDate())

var array : [Datable] = [x, y]

var x2 : Datable = Type1(date:NSDate())
var y2 : Datable = Type2(date:NSDate())

array.append(x2)
array.append(y2)

Comments

0

The easiest way is use map:

var depRefList: Array<Datable> = fetchDepRefs().map { $0 as Datable }
var depObsList: Array<Datable> = fetchDepObss().map { $0 as Datable }
var allDeps = (depRefList + depObsList)
            .sort { $0.date.timeIntervalSince1970 > $1.date.timeIntervalSince1970 }

since depRefList is [Datable], and fetchDepRefs() is [DEPref], Thay are different type, So it's neccecary to transfer [DEPref] to [Datable], The map function will do this for you. The flowing code:

var depRefList: Array<Datable> = fetchDepRefs().map { $0 as Datable }

is equal to:

let depRefs: [DEPref] = fetchDepRefs()

var datables = [Datable]()

for depRef in depRefs {
    let datable = depRef as Datable
    datables.append(datable)
}

var depRefList: Array<Datable> = datables

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.