4 Replies
      Latest reply: Jan 22, 2017 3:37 PM by eskimo RSS
      stcocoa Level 1 Level 1 (0 points)

        Hi,

         

        There are two arrays with type Array<Dictionary<String,Any>>.

         

        and the two array are not sorted, so even if they have a same contents, the order in array is not the same maybe.

         

        I want to compare two arrays and figure out they have same contents.

         

        simple example.

         

        Array A is  [a, b, c]  and Array [b, c, a] , I want to get true in boolean. (true return)

         

        [a, b, c] and [a, b, c, d] are regarded as not same array. (false retun)

        surely, [a, b, c] and [x, g, t] are regarded as not same array too. (false return)

         

        Is there any way to do this compare ?

         

        Thanks

        • Re: Compare two array have a same contents
          rsharp Level 3 Level 3 (155 points)

          You would need to write a function that would normalize the two values before comparisson.  For example, in your simplified example:

           

          func areArraysEquivalent(first aFirstArray: [Int], second aSecondArray: [Int]) -> Bool {
               return aFirstArray.sorted() == aSecondArray.sorted()
          }
          
          let array1 = [1, 2, 3]
          let array2 = [2, 1, 3]
          let array3 = [1, 2]
          
          areArraysEquivalent(first: array1, second: array2)  // true
          areArraysEquivalent(first: array1, second: array3)  // false
          
            • Re: Compare two array have a same contents
              stcocoa Level 1 Level 1 (0 points)

              Thanks, rsharp ^ ^

               

              actually, I do sort successfully.

               

              But there is one problem.

               

              When I compare two arrays by == , thre is a error msg that 'Binary operator '==' cannot be applied to two 'Array<Dictionary<String, Any>>' operands'.

               

              Any way to solve this ?

                • Re: Compare two array have a same contents
                  rsharp Level 3 Level 3 (155 points)

                  You'll need to pick apart the various pieces of your complex data type and check for equivalence.


                  Break down your structure into pieces.  For example, you'll need to first see if your 'Any' type is equivalent.  I would also ask if you need to use 'Any' or if you can use a more specific type?  If using a specific type, your work will be easier.

                   

                  Beyond the type check, I see three things you'll need to do:

                   

                  • Compare the count of array items.  If they are different, return false
                  • Perhaps convert the Dictionary<String, Any> into a sorted array of tuples where each tuple contains a String-Any pair.  Then, put those sorted arrays into a main array and sort that.  i.e. each Array<Dictionary<String, Any>> is turned into a structure that is completely sorted.
                  • Iterate through the index of both arrays (you've already proven they hold the same number of items) and use == on their elements. You'll need to write a custom implementation of == to work with those elemnts (array of tuples).
              • Re: Compare two array have a same contents
                eskimo Apple Staff Apple Staff (7,190 points)

                There are two arrays with type Array>.

                I want to compare two arrays and figure out they have same contents.

                There’s no way to do this in the general case because there's no way to compare values of type Any.

                When I see questions like this I immediately think, “Why do you have an array of [String:Any]?”  In my experience most folks have this problem because they’ve read some general data structure (JSON, property list, or whatever) and are working with the low-level import format.  IMO it’s better to sort out this problem when you bring the data into Swift.  That is:

                1. On import, convert [String:Any] to some defined-in-Swift model value (class or struct)

                2. Write Swift code that works with that model value

                3. On export, convert the model value back to the external representation

                Share and Enjoy

                Quinn “The Eskimo!”
                Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                let myEmail = "eskimo" + "1" + "@apple.com"