Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrays of Int arrays. Storing duplicates in order only

I need to store an array of Int array for ordered duplicates (which are in a Array).

Example:

  • Given array:
    mainArray = [7, 7, 3, 2, 2, 2, 1, 7, 5, 5]

Now i need to create a 2D array of int Array.
Example:

Array [][] = [
               [7, 7], 
               [3], 
               [2, 2, 2], 
               [1], 
               [7],
               [5, 5]
             ]

Here is what I have:

for var i = 0; i < val.count; i++ {
    var columnArray = Array<Int>()
    for var j in 0...9 {
        if oldNum == val[j]{
            columnArray.append(val[j])
        }
        else {
            array.append(columnArray);
            //j += 1
            break;
        }
        oldNum = val[j];
        j += 1
    }
}
like image 510
Shank Avatar asked Feb 11 '16 00:02

Shank


4 Answers

You can use the reduce method.

let result = numbers.reduce([[Int]]()) { (var result, num) -> [[Int]] in
    if var lastSequence = result.last where lastSequence.first == num {
        result[result.count-1].append(num)
    } else {
        result.append([num])
    }
    return result
}

How does the reduce work?

reduce does apply the logic in the closure to an empty 2D array of integers ([[Int]]) and the first elm of numbers.

Then it is applied again to the result of the previous iteration and the second array of integers... and so on.

What does happen in the closure?

The if does check whether the number in the last array added to the result is equals to the integer currently examined. If so that integer is added to that array.

Otherwise a new array containing only the new integer is added to the result.

Test

[[7, 7], [3], [2, 2, 2], [1], [7], [5, 5]]
like image 149
Luca Angeletti Avatar answered Nov 15 '22 07:11

Luca Angeletti


Another approach extending collections where elements are equatable

extension Collection where Element: Equatable {
    var grouped: [[Element]] {
        var result: [[Element]] = []
        for element in self {
            if element == result.last?.last {
                result[result.index(before: result.endIndex)].append(element)
            } else {
                result.append([element])
            }
        }
        return result
    }
}

let array = [7, 7, 3, 2, 2, 2, 1, 7, 5, 5]

array.grouped  // [[7, 7], [3], [2, 2, 2], [1], [7], [5, 5]]
like image 45
Leo Dabus Avatar answered Nov 15 '22 09:11

Leo Dabus


This is a programming logic problem problem. Your current code is totally wrong.

Here's one way you could solve it:

Start out by sorting your starting array. call that inputArray.

Create new, empty output "outerArray" and "innerArray" variables. Then loop through the entries in inputArray, testing for changes in value. If the value is the same as the last value, add that value to "innerArray". If the value has changed, save the previous innerArray to the outerArray and create a new, empty array and save it to innerArray.

like image 31
Duncan C Avatar answered Nov 15 '22 09:11

Duncan C


The following code will give you what you need...

let mainArray = [7, 7, 3, 2, 2, 2, 1, 7, 5, 5]
var newArray: [[Int]] = []

for var i=0; i < mainArray.count; i++ {
    let element = mainArray[i]
    if mainArray.indexOf(element) == i {
      var subArray = mainArray.filter({ $0 == element })
      newArray.append(subArray)
    }
}

print(newArray) // -> [[7, 7, 7], [3], [2, 2, 2], [1], [5, 5]]
like image 45
Michael Avatar answered Nov 15 '22 08:11

Michael