Ambiguous Use of 'Filter' When Converting Project to Swift 4

Ambiguous use of 'filter' when converting project to Swift 4

To solve this, declare the type of the variable before you return it.

let x: [Character] = input.filter{/**/}
return x

This disambiguates the return type of the filter{} method.

Ambiguous use of 'filter' after migration to Swift 4.2

You have added your own filter method to Dictionary, this is not necessary, as Swift already has such a method: filter.

This method seems to be added in Swift 4.2, which explains why you didn't get the error before. Since Swift has this method provided for you now, you can safely delete the filter that you wrote.

Swift 4 - Ambigous reference to member '' (iOS 11)

The value is a generic method and when comparing with a literal (that is, something without a defined type), the compiler has a problem to figure out what type to infer there. One workaround is to add as Int to one side of the expression:

(slightly rewritten for readability)

let alerts = realm.objects(Alerts).filter(NSPredicate(format: "department != nil")).sorted(byKeyPath: "departmentNumber")

let isRedLevel: (DangerLevel) -> Bool = { dangerLevel in
($0.level.value as Int) == 4
}
let hasRedLevels: (Alert) -> Bool = { alert in
alert.dangerLevels.contains(where: isRedLevel)
}

redCount = alerts!.filter(hasRedLevels).count

What would also work is to define a constant:

let redAlertType: Int = 4

and use it instead of the literal 4.

Wanted to see if anyone has any insight to why an ambigious use of subscript error is created in one project vs. another in swift

As is explained in the answer you linked to, Foundation containers (NSArray, NSDictionary etc) are untyped. So, currentSelectionCells[row] returns AnyObject. Swift won't let you subscript an AnyObject since it may not be a container. It could literally be anything.

If you look closely at the code in the AppCoda article where you have

for row in 0...((currentSectionCells ).count - 1) {

they have

for row in 0...((currentSectionCells as! [[String: AnyObject]]).count - 1) {

They have bridged currentSelectCells to a Swift array containing a Swift dictionary of String:AnyObjectso when they later say currentSelectionCells[row] they get back a dictionary [String:AnyObject]. This is subscriptable and Swift is happy.

So, there is an easy way to convert a plist to a Swift array. It is generally best to convert Foundation containers to Swift containers at the earliest opportunity since then you get the advantages of member typing. It would have been better if they had implemented loadCellDescriptors as something like:

var cellDescriptors: [[String:AnyObject]]!

func loadCellDescriptors() {
if let path = NSBundle.mainBundle().pathForResource("CellDescriptor", ofType: "plist") {
let plist = NSMutableArray(contentsOfFile: path)
cellDescriptors = plist as! [[String:AnyObject]]
getIndicesOfVisibleRows()
tblExpandable.reloadData()
}
}

Explain this code: uses a string as filter function

It's using:

// MARK: Filtering
/**
Returns a `Results` containing all objects matching the given predicate in the collection.
- parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments.
*/
func filter(_ predicateFormat: String, _ args: Any...) -> Results<Element>

Source: RealmCollectiton

Under the hood, it's using NSPredicate(format:), it "hides" it by simplifying and avoid writing each time NSPredicate(format: ...), and should use KeyPath too. More explanation on what you can do with that here at Predicate Format String Syntax.

not

func filter(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> [Self.Element]

on Sequence

Here a sample code to illustrate/mimic:

class TestClass: NSObject {
@objc var title: String
init(title: String) {
self.title = title
super.init()
}
override var description: String {
"TestClass - title: \(title)"
}
}

let objects: [TestClass] = [TestClass(title: "Title1"), TestClass(title: "Title2")]

// In a "Swifty way
let searchedText = "Title1"
let filtered1 = objects.filter {
$0.title == searchedText
}
print("filtered1: \(filtered1)")

// With a NSPredicate, which is more Objective-C (filtering on NSArray for instance)
// But also there is a translation with Core-Data, and then fetching optimization
let filtered2 = objects.filter {
NSPredicate(format: "title == 'Title1'").evaluate(with: $0)
}
print("filtered2: \(filtered2)")
// Same, but with avoiding hard coding strings
let filtered3 = objects.filter {
NSPredicate(format: "%K == %@", #keyPath(TestClass.title), searchedText).evaluate(with: $0)
}
print("filtered3: \(filtered3)")

extension Sequence {
func filter(_ predicateFormat: String, _ args: Any...) -> [Element] {
let predicate = NSPredicate(format: predicateFormat, argumentArray: args)
return self.filter({ predicate.evaluate(with: $0) })
}
}

// With an extension similar to what does Realm
let filtered4 = objects.filter("title == 'Title1'")
print("filtered4: \(filtered4)")

// With an extension similar to what does Realm, and less hard coded string (cf filtered3 construction)
let filtered5 = objects.filter("%K == %@", #keyPath(TestClass.title), searchedText)
print("filtered5: \(filtered5)")

With output:

$>filtered1: [TestClass - title: Title1]
$>filtered2: [TestClass - title: Title1]
$>filtered3: [TestClass - title: Title1]
$>filtered4: [TestClass - title: Title1]
$>filtered5: [TestClass - title: Title1]

Type of expression is ambiguous without more context. SocketEngine Class

You should not update the library's functions to Swift 4 manually.

Download the library again, it has now been updated to Swift 4.

Dynamic Filter in Sqlite.swift to check if a column is not null

To check for inequality between an expression and an optional value with SQLite.swift, you need !==, not !=

Here is the relevant code:

https://github.com/stephencelis/SQLite.swift/blob/master/Sources/SQLite/Typed/Operators.swift#L450

You can also see this in the tests:

https://github.com/stephencelis/SQLite.swift/blob/master/Tests/SQLiteTests/Typed/OperatorsTests.swift#L214

When you don't find something in the docs, the tests in this project are a good place to look for answers

Ambiguous use of 'init'

I found solution for my issue , I use same method name with deferent parameter in Objective-C Class

- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
Dragable:(BOOL)isDragable
updateCoordinate:(updateCoordinate)updateCoordinate;

and

- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
Dragable:(BOOL)isDragable;

just used NS_SWIFT_NAME to change names and it's work fine

NS_SWIFT_NAME(init(withUpdateCoordinateAndCoordinate:isDragable:withUpdateCoordinate:));

and

NS_SWIFT_NAME(init(withCoordinate:isDragable:));


Related Topics



Leave a reply



Submit