1

suppose i have a array that have 10 elements. say,

var ArrayElemts : ["1","2","3","4","5","6","7","8","9","10","11"]

Now how can i keep the elements from 0 t0 5 in one array set and 6 to 10 to another array set?

1
  • You have 11 elements in your array sample Commented May 28, 2017 at 16:09

4 Answers 4

2

Use [0...5] to create an ArraySlice and then Array to convert that back to an array:

var arrayElemts = ["1","2","3","4","5","6","7","8","9","10","11"]

let first = Array(arrayElemts[0...5])
let second = Array(arrayElemts[6...10])

print(first)   // ["1", "2", "3", "4", "5", "6"]
print(second)  // ["7", "8", "9", "10", "11"]
Sign up to request clarification or add additional context in comments.

1 Comment

No need to say that an array.count check is needed to avoid crashing with an array with less than 11 elements
2

The easiest option is the following:

let partition1 = array.filter { Int($0) ?? 0 <= 5 }
let partition2 = array.filter { Int($0) ?? 0 > 5 }

Conversion to numbers should be the first step though. You should never work with strings as if they were numbers.

let numbers = array.flatMap { Int($0) }

let partition1 = numbers.filter { $0 <= 5 }
let partition2 = numbers.filter { $0 > 5 }

If we suppose the array is sorted, there are easier options:

let sorted = numbers.sorted()
let partition1: [Int]
let partition2: [Int]

if let partition2start = sorted.index(where: { $0 > 5 }) {
    partition1 = Array(sorted.prefix(upTo: partition2start))
    partition2 = Array(sorted.suffix(from: partition2start))
} else {
    partition1 = sorted
    partition2 = []
}

which is what the native partition method can do:

var numbers = array.flatMap { Int($0) }
let index = numbers.partition { $0 > 5 }
let partition1 = Array(numbers.prefix(upTo: index))
let partition2 = Array(numbers.suffix(from: index))

Note the method changes the original array.

Comments

1

Breaking the array up into N-sized chunks

The other answers show you how to "statically" partition the original array in different arrays using ArraySlice:s. Given your description, possibly you want to, generally, break up your original array into N-sized chunks (here: n = 5).

We could use the sequence(state:next) to implement such a chunk(bySize:) method as an extension to Collection:

extension Collection {
    func chunk(bySize size: IndexDistance) -> [SubSequence] {
        precondition(size > 0, "Chunk size must be a positive integer.")
        return sequence(
            state: (startIndex, index(startIndex, offsetBy: size, limitedBy: endIndex) ?? endIndex),
            next: { indices in
            guard indices.0 != self.endIndex else { return nil }
            indices.1 = self.index(indices.0, offsetBy: size, limitedBy: self.endIndex) ?? self.endIndex
            return (self[indices.0..<indices.1], indices.0 = indices.1).0
        }).map { $0 }
    }
}

Applied to your example:

var arrayElements = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
let partitions = arrayElements.chunk(bySize: 5)
/* [["1", "2", "3", "4", "5"],
    ["6", "7", "8", "9", "10"],
    ["11"]] */

The chunk(bySize:) method will break up the array into bySize-sized chunks, as well as (possible) a smaller chunk for the final partition.


However, as much as I'd like to try to use the sequence(state:next) function (not needing to use any mutable intermediate variables other than state), the implementation above is quite bloated and difficult to read, so (as for so many other cases ...) we are probably better off simply using a while loop:

extension Collection {
    func chunk(bySize size: IndexDistance) -> [SubSequence] {
        precondition(size > 0, "Chunk size must be a positive integer.")
        var chunks: [SubSequence] = []
        var from = startIndex
        while let to = index(from, offsetBy: size, limitedBy: endIndex) {
            chunks.append(self[from..<to])
            from = to
        }
        if from != endIndex { chunks.append(self[from..<endIndex]) }
        return chunks
    }
}

Comments

0

lol I don't see why there are so complicated answers here (Consider the "array" variable as is -> [Int], not [Any]) So the first approach is just for Number types. The second one should do it

Simply:

let array = [0,1,2,3,4,5,6,7,8,9,10]
//For instance..
var arrayA = ["A","B","C","D","E","F","G"]

//First 6 elements
let arrayOfFirstFour = array.filter({
    return $0 <= 5 ? true : false
})

//Remaining  elements:
let restOfArray = array.filter({
    return $0 > 5 ? true : false
})

let elementsToFourth = arrayA.prefix(upTo: 4)
let elementsAfterFourth = arrayA.suffix(from: 4)
print(arrayOfFirstFour)
print(restOfArray)
print(elementsToFourth)
print(elementsAfterFourth)

//[0, 1, 2, 3, 4, 5]
//[6, 7, 8, 9, 10]
//["A", "B", "C", "D"]
//["E", "F", "G"]

5 Comments

Talking about unnecessary complications let arrayOfFirstFour = array.filter{ $0 <= 5 }
If the intent is to get the first n elements just use array.prefix(n)
What if the array is ["x", "a", "1", "4", "foo", "11", "3"]? I believe the values of the elements in the the array of the question are simply examples, whereas the question covers splitting the elements based on their positions (not values!), so your value-based filters are somewhat misleading. The prefix and suffix approaches are good though (as has already been covered in @Sulthan:s answer), given that the array is to be split into exactly two arrays (without actually removing the "split" element).
@LeoDabus : Maybe I am a bit sceptical, but the ternary operator seems a bit like (I know what I am doing) :D
Note that prefix(n) is different from prefix(upTo: n)

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.