2016-03-28 15 views
5

Tôi muốn có thể sửa đổi mảng đối tượng của mình bằng cách sử dụng map trong Swift khi đang bay mà không lặp qua từng phần tử.Bản đồ sửa đổi mảng đối tượng trong Swift 2.2 (3.0)

Trước đây đã có thể làm một cái gì đó như thế này (mô tả chi tiết hơn here:

gnomes = gnomes.map { (var gnome: Gnome) -> Gnome in 
    gnome.age = 140 
    return gnome 
} 

Cám ơn Erica Sadun và những người khác, đề xuất mới đã trải qua và chúng tôi bây giờ nhận được thoát khỏi C-style vòng và sử dụng var bên trong vòng lặp.

trong trường hợp của tôi, tôi đang xin giấy chứng nhận cảnh báo để loại bỏ các var trong đó một lỗi gnome tôi là một hằng số (tự nhiên)

Câu hỏi của tôi là: Làm thế nào để chúng ta thay đổi mảng bên trong một map hoặc các vòng theo kiểu mới cho vấn đề đó được chuẩn bị đầy đủ cho Swift 3.0?

Trả lời

13

Nếu bạn muốn giữ lại cú pháp đó, chỉ cần sử dụng một (có thể thay đổi) tạm thời biến

gnomes = gnomes.map { (gnome: Gnome) -> Gnome in 
    var mutableGnome = gnome 
    mutableGnome.age = 140 
    return mutableGnome 
} 
12

(Dưới sau trường hợp Gnome là một loại tài liệu tham khảo; một lớp - kể từ khi bạn đã không cho chúng ta thấy làm thế nào bạn đã xác định Gnome Đối với trường hợp Gnome như kiểu giá trị (một struct), xem @. vadian: s câu trả lời)


Việc loại bỏ var sẽ không ảnh hưởng đến sử dụng .map để đột biến có thể thay đổi thành viên của một mảng của tham khảo đối tượng loại. Tức là, bạn chỉ có thể sử dụng phương pháp cũ của mình (bỏ qua tuy nhiên, var trong chữ ký đóng cửa .map).

class Gnome { 
    var age = 42 
} 

var gnomes = [Gnome(), Gnome(), Gnome()] 

gnomes = gnomes.map { 
    $0.age = 150 
    return $0 
} 

/* result */ 
gnomes.forEach { print($0.age) } // 3x 150 

Tuy nhiên, trong trường hợp bạn chỉ muốn sửa đổi mảng ban đầu của bạn chứ không phải là gán kết quả của .map đến một mảng mới, .forEach có thể là một lựa chọn thích hợp hơn .map.

gnomes.forEach { $0.age = 140 } 

/* result */ 
gnomes.forEach { print($0.age) } // 3x 140 
+0

trả về lỗi '' $ 0 là không thay đổi''. Đó là lỗi của tôi.Tôi nên có chính xác hơn: (Tôi đang sử dụng cấu trúc thay vì các lớp học, tôi đặt cược rằng những gì làm cho họ bất biến theo mặc định – kernelpanic

+0

@ kernelpanic Vì bạn đã không cho chúng tôi thấy bạn 'Gnome' lớp học, tôi đã bao gồm một trong của riêng tôi Bạn có chắc chắn thuộc tính 'age' của lớp của bạn là một cái có thể thay đổi được (cũng như mảng gnomes của bạn)? Các công trình trên tốt cho tôi trên Swift 2.2 và Xcode 7.3. – dfri

+0

@dfri Tôi nghi ngờ rằng' Gnome' là một struct – vadian

1

Given:

struct Gnome { 
    var age: Int = 0 
} 

var gnomes = Array(count: 5, repeatedValue: Gnome()) 

... có hai tùy chọn phong nha. Đầu tiên là như @vadian đặt nó:

gnomes = gnomes.map{ 
    var gnome = $0 
    gnome.age = 70 
    return gnome 
} 

Trong khi thứ hai giữ quyền kiểm soát "lão hóa" private và đơn giản hóa bản đồ tại thời điểm cuộc gọi:

struct Gnome { 
    private(set) var age: Int = 0 

    func aged(age: Int) -> Gnome { 
     var gnome = self 
     gnome.age = age 
     // any other ageing related changes 
     return gnome 
    } 
} 

gnomes = gnomes.map{ $0.aged(140) } 

Tất nhiên, các loại tài liệu tham khảo vẫn có họ đặt trong lập trình, mà cũng có thể phù hợp hơn trong trường hợp này. Ma sát chúng ta đang trải qua ở đây gợi ý rằng chúng ta đang cố gắng đối xử với những cấu trúc này như thể chúng là vật thể. Nếu đó là hành vi bạn cần, thì bạn nên xem xét triển khai Gnome dưới dạng class.

Các vấn đề liên quan