2

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.

enter image description here

4
  • Do you want to show only movies which were selected multiple times? e.g. Batman v Superman? Commented Sep 12, 2016 at 21:57
  • @tech4242 i want to show all the movies selected. If a movie was chosen multiple times I'll change the blue box to green in the table view. That make sense? Commented Sep 12, 2016 at 21:58
  • I'm sorry but I'm not sure I can follow you - what do you mean by identity? Commented Sep 12, 2016 at 21:59
  • So the users can easily identify that they both selected the same movie Commented Sep 12, 2016 at 22:03

4 Answers 4

6

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")
}
Sign up to request clarification or add additional context in comments.

7 Comments

That won't work. movies.contains(movie) will always be true.
Right I fully understand that but this is just the duplicate movies. How do I also show the flash and avengers while showing that batman was chosen by both people? It's hard to make it clear over text I'm sorry.
Sorry I'll try to make it more clear. This is the flow of the app. One user selects movies from a list of movies. Another user selects movies from a list of movies. I combine both the lists into one array. I want to display the list and display if there were any duplicates of the same movie as this would show they had selected the same movie.
@PoisonedApps Ok, I have edited my answer :) Now the dictionary holds the occurrences and you can act accordingly => if a certain key value has value (int) > 1 => show key
Thank you! I'll try that
|
3

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:

Comments

0

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)
        }
    }

Comments

0

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.

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.