Reputation: 726
I have an array of custom objects and want to know how to identify which objects are duplicates. I know how to remove the duplicates but that is not functionality I'm after. Im using swift 2.
Example:
var movies: [Movie] = ["Batman v Superman: Dawn of Justice", "Batman v Superman: Dawn of Justice", "Deadpool"," "Deadpool", "Hardcore Henry", "Jason Bourne", "Jurassic World"]
So i want to show a table view with the list of movies above but with "Batman" and "Deadpool" highlighted.
For more clarity on what I'm trying to achieve look at the screenshot. I have a list of movies that two users select in a previous view controller. I want to display the selected movies in a table view. I want to specifically show if there were movies that both people selected.
Upvotes: 2
Views: 5416
Reputation: 73236
I generally try to avoid posting answers with code entirely written by someone else (MIT License), but the reference below is such a neat fit for this question that I believe it's worth including as an answer.
The solution use the same technique as the accepted answer, but on a more general form (made compact with a neat subscript
extension to Dictionary
): the freq()
dictionary extension from GitHub user oisdk's excellent SwiftSequence framework (MIT License):
/* ---------------------------------------------------------------------------
source: GitHub user oisdk:
https://github.com/oisdk/SwiftSequence/blob/master/Sources/Categorise.swift */
private extension Dictionary {
subscript(key: Key, or or: Value) -> Value {
get { return self[key] ?? or }
set { self[key] = newValue }
}
}
public extension SequenceType where Generator.Element : Hashable {
// MARK: Frequencies
/**
Returns a dictionary where the keys are the elements of self, and
the values are their respective frequencies
```swift
[0, 3, 0, 1, 1, 3, 2, 3, 1, 0].freqs()
// [2: 1, 0: 3, 3: 3, 1: 3]
```
*/
@warn_unused_result
func freqs() -> [Generator.Element:Int] {
var freqs: [Generator.Element:Int] = [:]
for el in self { freqs[el, or: 0] += 1 }
return freqs
}
}
/* --------------------------------------------------------------------------- */
/* example usage */
let movies = ["Batman","Batman","Flash","Avengers"]
print(movies.freqs()) // ["Avengers": 1, "Flash": 1, "Batman": 2]
Have a look at the framework for lots of other sequence goodies:
Upvotes: 3
Reputation: 2468
Based on your comment I have made a simple example with string arrays, which can easily be converted to your movie type:
let movies = ["Batman","Batman","Flash","Avengers"]
var movieCounts:[String:Int] = [:]
for movie in movies {
movieCounts[movie] = (movieCounts[movie] ?? 0) + 1
}
And you can test it like so:
for (key, value) in movieCounts {
print("\(key) has been selected \(value) time/s")
}
Upvotes: 6
Reputation: 7595
Not sure what functionalities you want to make.
If just for list of items, you can use swift dictionary to count duplicates, by using movie name as key and count as value starting by 0.
If you want to highlight, you can use different style when you populate the table in the delegate method by checking if the item has duplicates.
Upvotes: 0
Reputation: 1029
Why not adding an id in the Movie object
and compare the two arrays searching the same object.
public class Movie:Equatable{
var id=NSUUID().UUIDString
}
public func ==(lhs: Movie, rhs: Movie) -> Bool{
return lhs.id == rhs.id
}
Comparing the arrays:
var moviesA=[Movie]()
var moviesB=[Movie]()
var sharedMovies=[Movie]()
for movie in moviesA{
if moviesB.contains(movie){
sharedMovies.append(movie)
}
}
Upvotes: 0