Có nhiều cách ưa thích để làm điều đó với bộ lọc nhưng hầu hết có lẽ sẽ yêu cầu hai vượt chứ không phải là một, vì vậy bạn cũng có thể chỉ cần sử dụng một for-loop.
Không gian dự phòng phía trước có thể tạo sự khác biệt lớn trong trường hợp này vì nguồn lớn sẽ tránh phân bổ lại không cần thiết khi mảng mới phát triển và việc tính khoảng trống cần thiết là không đổi trên các mảng.
// could make this take a more generic random-access collection source
// if needed, or just make it an array extension instead
func splitAlternating<T>(source: [T]) -> ([T],[T]) {
var evens: [T] = [], odds: [T] = []
evens.reserveCapacity(source.count/2 + 1)
odds.reserveCapacity(source.count/2)
for idx in indices(source) {
if idx % 2 == 0 {
evens.append(source[idx])
}
else {
odds.append(source[idx])
}
}
return (evens,odds)
}
let a = [0,1,2,3,4,5,6]
splitAlternating(a) // ([0, 2, 4, 6], [1, 3, 5])
Nếu hiệu suất là thực sự quan trọng, bạn có thể sử dụng source.withUnsafeBufferPointer
để truy cập các yếu tố nguồn, để tránh các giới hạn chỉ số kiểm tra.
Nếu mảng thực sự rất lớn, và bạn sẽ không sử dụng dữ liệu kết quả ngoại trừ mẫu một số lượng nhỏ các yếu tố, bạn có thể xem xét sử dụng chế độ xem lười thay thế. t sử dụng nhiều ở đây vì nó trả về trình tự không phải là một bộ sưu tập - bạn có thể cần phải viết của riêng bạn).
Nguồn
2015-03-15 02:59:32
Điều tốt nhất bạn sẽ nhận được là 'O (n) '. Chỉ cần tạo hai mảng mới và lặp qua mảng cũ, xen kẽ nơi bạn đặt một phần tử trên mỗi lần lặp. – royhowie