0

I have a question and unfortunately not found anywhere responses.

I'll describe the problem in a simple example. I have an array of objects. Each object contains the id, name, count. This array is the result of parsing the data from the server. It is taken as the first.

I also have a second array taken from another server. This is the same array id, name, count.

My question is as follows. The first array has 20 elements, then each of this element I want to compare with an array of the other. The second array is the parse. You may need to use a loop and check whether every element in the first array is in the second or not?

//
//  ViewController.swift
//  ParseSearching
//
//  Created by Mateusz Fraczek on 21.07.2015.
//  Copyright (c) 2015 universeldev. All rights reserved.
//

import UIKit
import Parse

struct Model : Equatable {
    var ide: String!
    var name: String!
    var count: String!
}

func ==(a: Model, b: Model) -> Bool {
    return a.ide == b.ide && a.name == b.name && a.count == b.count
}

extension Array {

    func indexesOfSubset<T : Equatable>(objects : [T]) -> [Int] {

        // Create storage for filtered objects and results
        var unusedObjects = objects
        var result : [Int] = []

        // Enumerate through all objects in array
        for (index, obj) in enumerate(self) {

            // Enumerate again through all objects that has not been found
            for x in unusedObjects {

                // If we hit match, append result, remove it from usused objects
                if obj as! T == x {
                    result.append(index)
                    unusedObjects = unusedObjects.filter( { $0 != x } )
                    break
                }
            }
        }

        // Get results
        return result
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var firstArray = [Model]()
        var resultsArray = [Model]()


        firstArray.append(Model(ide: "xyz1", name: "name1", count: "0"))
        firstArray.append(Model(ide: "xyz2", name: "name2", count: "0"))
        firstArray.append(Model(ide: "xyz3", name: "name3", count: "0"))
        firstArray.append(Model(ide: "xyz4", name: "name4", count: "0"))

//        let testObject = PFObject(className: "TestObject")
//        testObject["ide"] = "xyz1"
//        testObject["name"] = "name1"
//        testObject["count"] = "0"
//        testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
//            println("Object has been saved.")
//        }


        var query = PFQuery(className: "TestObject")

        query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
            if let object = objects as? [PFObject] {
                for obj in object {
                    var id = obj.objectForKey("ide") as! String
                    var name = obj.objectForKey("name") as! String
                    var count = obj.objectForKey("count") as! String

                    var model = Model(ide: id, name: name, count: count)

                    resultsArray.append(model)
                    println(resultsArray)
                    let indexes = firstArray.indexesOfSubset(resultsArray)

                    println("Indexes \(indexes) ")
                }
            }
        }



    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



}
8
  • Do you want to check id by id name by name or count by count? Commented Jul 21, 2015 at 6:32
  • I would like to find object in second array which are in first array. Commented Jul 21, 2015 at 6:37
  • If you explain with an example it would be easy for me to guide you. Commented Jul 21, 2015 at 6:40
  • You have some code lower. Commented Jul 21, 2015 at 6:50
  • Try to do something like this for loop(){ if contains(secondArray,first array[0] valueForKey "id"){print "Yes Contain"} }.Same way you can check other key values. Commented Jul 21, 2015 at 6:54

4 Answers 4

1

This is how you can do:

Swift 1:

var array = ["1", "2", "3"]
var contained = contains(array, "2")
println(contained ? "yes" : "no")

Swift 2:

var array = ["1", "2", "3"]
var contained = array.contains("2")
println(contained ? "yes" : "no")
Sign up to request clarification or add additional context in comments.

Comments

0

In order to find indexes of subset, it would be better to use something new in SWIFT, what do you say? So lets use generics and make solution that would work in the future, when your object changes, or you will use different objects altogether. Lets create extension to your array:

extension Array {

    func indexesOfSubset<T : Equatable>(objects : [T]) -> [Int] {

        // Create storage for filtered objects and results
        var unusedObjects = objects
        var result : [Int] = []

        // Enumerate through all objects in array
        for (index, obj) in enumerate(self) {

            // Enumerate again through all objects that has not been found
            for x in unusedObjects {

                // If we hit match, append result, remove it from usused objects
                if obj as! T == x {
                    result.append(index)
                    unusedObjects = unusedObjects.filter( { $0 != x } )
                    break
                }
            }
        }

        // Get results
        return result
    }
}

Now you can use this method to find objects using:

let sameIndexes = allData.indexesOfSubset(fetchedData)

Of course, fetched data and all data must be the same data type, in your case [Model]. You also have to make sure that you can compare those two objects properly, to do that, you have to create comparator taking your data type like this:

public func ==(a: Model, b: Model) -> Bool {
    return a.id == b.id && a.name == b.name && a.count == b.count
}

Also, in order for it to work, you have to make your object conform to Equatable protocol, so do that:

struct Model : Equatable {

Now when you compare two same Model objects, you will get compare == true and not an error :) Hope it helps!

Edit: Here is test gist where you can find everything including stuff from comments + how to use it

13 Comments

Error here: for (index, obj) in enumerate(self)
I've edited my answer for your better understanding - you have to make it as extension to an array :)
Thank you. But how can I use it with Model? In my code I can see cannot invoke indexesOfSubset with argument list of type Model.
This method is made for searching array against array. So if you do firstArray.indexesOfSubset([model]), it should find you whether there is a match :) And of course, if you have more model objects, then you just do firstArray.indexesOfSubset([model1, model2]), and it will give you indexes in the first array, when it found a match.
You should also extend Model with Equatable in order to make this work.
|
0

I am in no way an expert but I would use isEqualToArray inside NSarray class.

The function inside the class compares the receiving array to another array.

SWIFT
func isEqualToArray(_ otherArray: [AnyObject]) -> Bool

Return Values
YES if the contents of otherArray are equal to the contents of the receiving array, otherwise NO

Comments

0

Use filter and contains

func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
    return lhs.intConstant == rhs.intConstant && lhs.stringConstant == rhs.stringConstant
}

struct SomeStruct: Equatable {
    let intConstant:Int
    let stringConstant:String
}

var someStructOne = SomeStruct(intConstant: 1, stringConstant: "1")
var someStructTwo = SomeStruct(intConstant: 2, stringConstant: "2")
var someStructThree = SomeStruct(intConstant: 3, stringConstant: "4")
var someStructFour = SomeStruct(intConstant: 4, stringConstant: "4")
var someStructFive = SomeStruct(intConstant: 5, stringConstant: "5")


let structArrayOne = [someStructOne, someStructTwo, someStructThree]
let structArrayTwo = [someStructOne, someStructFour, someStructFive]

let structsInBothArrays = structArrayOne.filter({contains(structArrayTwo, $0)})

The trick here is making the struct conform to the Equatable ptotocol. You do this with the global function definition at the top which gives a definition of how to compare the two structs.

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.