programing

배열에서 구조체의 값 변경

powerit 2023. 8. 6. 10:27
반응형

배열에서 구조체의 값 변경

저는 구조체를 배열 안에 저장하고 구조체의 값을 for 루프에 접근하고 변경하고 싶습니다.

struct testing {
    var value:Int
}

var test1 = testing(value: 6 )

test1.value = 2
// this works with no issue

var test2 = testing(value: 12 )

var testings = [ test1, test2 ]

for test in testings{
    test.value = 3
// here I get the error:"Can not assign to 'value' in 'test'"
}

구조를 클래스로 바꾸면 작동합니다.구조물의 값을 어떻게 바꿀 수 있는지 누가 말해줄 수 있나요?

@MikeS가 말한 것 외에도, 구조는 가치 유형이라는 것을 기억하세요.그래서.for루프:

for test in testings {

배열 요소의 복사본이 에 할당됩니다.test변수.변경 사항은 다음 항목으로 제한됩니다.test배열 요소를 실제로 변경하지 않은 변수입니다.클래스는 참조 유형이므로 클래스에 대해 작동합니다. 따라서 값이 복사되지 않고 참조로 복사됩니다.test변수.

적절한 방법은 다음을 사용하는 것입니다.for인덱스별:

for index in 0..<testings.count {
    testings[index].value = 15
}

이 경우 사용자는 실제 구조 요소에 액세스하고 해당 요소의 복사본이 아닌 실제 구조 요소를 수정합니다.

어레이에서 값 유형 작업을 간소화하려면 다음 확장 기능(Swift 3)을 사용할 수 있습니다.

extension Array {
    mutating func modifyForEach(_ body: (_ index: Index, _ element: inout Element) -> ()) {
        for index in indices {
            modifyElement(atIndex: index) { body(index, &$0) }
        }
    }

    mutating func modifyElement(atIndex index: Index, _ modifyElement: (_ element: inout Element) -> ()) {
        var element = self[index]
        modifyElement(&element)
        self[index] = element
    }
}

사용 예:

testings.modifyElement(atIndex: 0) { $0.value = 99 }
testings.modifyForEach { $1.value *= 2 }
testings.modifyForEach { $1.value = $0 }

자, 저는 빠른 3 호환성을 위해 제 답변을 업데이트하려고 합니다.

많은 개체를 프로그래밍할 때 컬렉션 내에 있는 개체의 일부 값을 변경해야 합니다.이 예에서 우리는 구조의 배열을 가지고 있으며 특정 객체의 값을 변경해야 하는 조건이 주어집니다.이것은 어느 개발일에나 매우 흔한 일입니다.

인덱스를 사용하여 수정해야 하는 개체를 결정하는 대신 IMHO가 더 일반적인 if 조건을 사용하는 것을 선호합니다.

import Foundation

struct MyStruct: CustomDebugStringConvertible {
    var myValue:Int
    var debugDescription: String {
        return "struct is \(myValue)"
    }
}

let struct1 = MyStruct(myValue: 1)
let struct2 = MyStruct(myValue: 2)
let structArray = [struct1, struct2]

let newStructArray = structArray.map({ (myStruct) -> MyStruct in
    // You can check anything like:
    if myStruct.myValue == 1 {
        var modified = myStruct
        modified.myValue = 400
        return modified
    } else {
        return myStruct
    }
})

debugPrint(newStructArray)

모든 것에 주목하세요. 이 개발 방식이 더 안전합니다.

클래스는 참조 유형이므로 구조체에서 발생하는 것처럼 값을 변경하기 위해 복사본을 만들 필요가 없습니다.클래스에 동일한 예제 사용:

class MyClass: CustomDebugStringConvertible {
    var myValue:Int

    init(myValue: Int){
        self.myValue = myValue
    }

    var debugDescription: String {
        return "class is \(myValue)"
    }
}

let class1 = MyClass(myValue: 1)
let class2 = MyClass(myValue: 2)
let classArray = [class1, class2]

let newClassArray = classArray.map({ (myClass) -> MyClass in
    // You can check anything like:
    if myClass.myValue == 1 {
        myClass.myValue = 400
    }
    return myClass
})

debugPrint(newClassArray)

변경 방법ArrayStructs

모든 요소에 대해:

itemsArray.indices.forEach { itemsArray[$0].someValue = newValue }

특정 요소의 경우:

itemsArray.indices.filter { itemsArray[$0].propertyToCompare == true }
                  .forEach { itemsArray[$0].someValue = newValue }

당신은 좋은 답을 충분히 가지고 있습니다.좀 더 일반적인 관점에서 질문을 다루겠습니다.

값 유형과 값이 복사되는 의미를 더 잘 이해하기 위한 또 다른 예로 다음을 들 수 있습니다.

struct Item {
    var value:Int

}

func change (item: Item, with value: Int){
    item.value = value //  cannot assign to property: 'item' is a 'let' constant
}

이는 항목이 복사되고 항목이 들어오면 변경할 수 없기 때문입니다. 즉, 편의를 위해서입니다.

만들었나요?Item클래스 유형의 값을 변경할 수 있습니다.


var item2 = item1 // mutable COPY created
item2.value = 10
print(item2.value) // 10
print(item1.value) // 5

이것은 매우 까다로운 대답입니다.제 생각에, 당신은 이렇게 해서는 안 됩니다:

struct testing {
    var value:Int
}

var test1 = testing(value: 6)
var test2 = testing(value: 12)

var ary = [UnsafeMutablePointer<testing>].convertFromArrayLiteral(&test1, &test2)

for p in ary {
    p.memory.value = 3
}

if test1.value == test2.value {
    println("value: \(test1.value)")
}

Xcode 6.1의 경우 어레이 초기화는

var ary = [UnsafeMutablePointer<testing>](arrayLiteral: &test1, &test2)

지도 함수를 사용하여 이 효과를 얻을 수 있습니다. 기본적으로 새 배열을 만듭니다.

itemsArray = itemsArray.map { 
  var card = $0
  card.isDefault = aCard.token == token
  return card
} 

새로운 구조체 배열을 다시 작성하게 되었습니다. 아래 예제를 참조하십시오.

func updateDefaultCreditCard(token: String) {
    var updatedArray: [CreditCard] = []
    for aCard in self.creditcards {
        var card = aCard
        card.isDefault = aCard.token == token
        updatedArray.append(card)
    }
    self.creditcards = updatedArray
}

나는 안토니오의 대답을 꽤 논리적으로 시도했지만 놀랍게도 효과가 없었습니다.이 문제를 더 탐구하기 위해 저는 다음을 시도했습니다.

struct testing {
    var value:Int
}

var test1 = testing(value: 6 )
var test2 = testing(value: 12 )

var testings = [ test1, test2 ]

var test1b = testings[0]
test1b.value = 13

// I would assume this is same as test1, but it is not test1.value is still 6

// even trying 

testings[0].value = 23

// still the value of test1 did not change.
// so I think the only way is to change the whole of test1

test1 = test1b

언급URL : https://stackoverflow.com/questions/26371751/changing-the-value-of-struct-in-an-array

반응형