[내일배움캠프 7주차 (02/11)]

yeseul jang·2026년 2월 11일

내일배움캠프

목록 보기
11/32

♾️ 코딩테스트

lv2 - 프로세스

func solution(_ priorities:[Int], _ location:Int) -> Int {
	var result = 0
    var maxPriority = priorities.max()!
    var tuplePriority = priorities.enumerated().map { (index, value) in
        (index, value)
    }
    var newArray: [(Int, Int)] = []
    var index = 0
    
    while !tuplePriority.isEmpty {
        if index >= tuplePriority.count {
               index = 0
           }
        if tuplePriority[index].1 == maxPriority {
            newArray.append(tuplePriority[index])
            tuplePriority.remove(at: index)
            
            if let max = tuplePriority.map { $0.1 }.max() {
                maxPriority = max
            } 
        } else {
            index += 1
        }
    }
    
    for i in 0..<newArray.count {
        if newArray[i].0 == location {
            
            result = i + 1
        }
    }

    return result
}
  • 처음에 가진 인덱스를 기억해야 하기 때문에 인덱스를 키값으로 하고 중요도를 Dictionary로 하려고 했는데 Queue를 구현하는데는 순서가 중요해서 Tuple로 바꾸었다.
  • 처음에는 단순히 for문을 돌면서 하려고 했는데 생각해보니까 for문을 돌면서 원본 배열을 수정하면 의도한 대로 돌아가지 않을 것 같아서 while사용으로 변경했다.
  • 로직 보다 Tuple 사용이나 맨 처음에 Tuple에 인덱스와 값 넣는 걸 알아내는데 시간이 더 걸린것 같다.😔 기본 개념을 더 잘 학습해야겠다는 교훈을 얻었다.

📚 Array vs Dict vs Set

  • 자료 구조 선택 기준

📘 Array

  • 순서 중요

  • index 접근 필요

  • append(뒤에서 추가) 사용이 많이 예상될때

  • 큐/스택 구조가 필요할 경우

  • 정렬 기반 문제

  • removeLast : O(1)

  • removeFirst : O(n) - 큐로 응용할때 주의

  • remove(at:) : O(n) - 우선순위 큐 응용시 주의

📘 Dictionary

  • 빠른 검색 필요
  • key 기반 접근
  • 빈도수 count, 해시 문제, 중복 체크

📘 Set

  • 중복제거
  • contains 빠르게 확인 원할 때

📌 CoreData

🔎 CRUD

  • create: 데이터 생성
  • read: 데이터 읽기
  • update: 데이터 업데이트(쓰기)
  • delete: 데이터 삭제
  • CRUD는 네이티브 앱 내부에서도 일어날 수 있고, 서버에서도 일어날 수 있음

🔎 CoreData

  • 객체 그래프 관리 프레임워크(Object Graph Management Framework)
  • 앱에서 기기의 디스크에 데이터를 읽고 쓸 수 있게 돕는 프레임워크
  • Swift로 기기 내 디스크에 데이터를 저장할 수 있는 대표적인 방법
  • 객체를 만들고 저장하면 내부적으로 SQLite에 저장됨

🔎 중요!

Core DataDB가 아니라 객체 관리 시스템(데이터를 읽고 쓸 수 있게 돕는 프레임워크)
context는 작업 공간
save() 해야 반영
fetch는 조건 검색

  • Change Tracking
    - save()를 하면 context가 변경된 객체를 추적해서 변경된 것만 DB에 반영

🔎 구성 요소

NSPersistentContainer

  • 기본적으로 AppDelegate에 선언되어 있음(앱 전체에서 공유되기 때문)
  • CoreData 전체를 관리하는 컨테이너
    • 데이터 모델 로딩
    • contex 생성
    • persistent store(SQLite) 연결

NSManagedObjectContext (viewContext)

  • 실제 작업 공간
  • save()해야지 실제 DB 반영됨

NSManagedObject

  • 저장 객체
  • ex) PhoneBook EntityNSManagedObject 인스턴스로 만들어짐

🔎 코드

class ViewController: UIViewController {
    // 컨테이너 선언
    var container: NSPersistentContainer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 델리게이트에서 컨테이너 찾아옴 (앱 전체에서 사용하기 위함)
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        self.container = appDelegate.persistentContainer
        
        creatData(name: "sally", phoneNumber: "010-8888-8888")
    }
    // MARK: CREAT 데이터 만들기
    func creatData(name: String, phoneNumber: String) {
        // PhoneBook이라는 테이블 구조를 가져옴
        guard let entity = NSEntityDescription.entity(forEntityName: PhoneBook.className, in: self.container.viewContext) else { return }
        
        // 객체 생성하기 - 메모리 안에 객체가 생김
        let phoneBook = NSManagedObject(entity: entity, insertInto: self.container.viewContext)
        
        // 키를 기준으로 값을 넣음
        phoneBook.setValue(name, forKey: PhoneBook.Key.name) //name이라는 키를 찾아서 넣어주겠음
        phoneBook.setValue(phoneNumber, forKey: PhoneBook.Key.phoneNumber)
        // 위에서 차이가 일어난거임
        
        do { // save()를 해서 SQLite에 반영
            try self.container.viewContext.save()
            print("문맥 저장 성공")
        } catch {
            print("실패")
        }
    }
    
    // MARK: READ 데이터 읽기
    func readData() {
        do { // fetchRequest - 특정 조건의 데이터를 요청
            let phoneBooks = try self.container.viewContext.fetch(PhoneBook.fetchRequest())
            
            // PhoneBook을 NSManagedObject로 만들었기 때문에 다운캐스팅
            for phoneBook in phoneBooks as [NSManagedObject] {
                if let name = phoneBook.value(forKey: "name") as? String,
                   let phoneNumber = phoneBook.value(forKey: "phoneNumber") as? String {
                    print("name: \(name), phoneNumber: \(phoneNumber)")
                }
            }
        } catch {
            print("데이터 읽기 실패")
        }
    }
    
    // MARK: UPDATE 수정하기
    func updateData(currentName: String, updateName: String) {
        // 수정할 데이터를 찾기 위해서 fetchRequest 생성
        let fetchRequest = PhoneBook.fetchRequest()
        // 상세 조건을 추가함 - name == currentName
        fetchRequest.predicate = NSPredicate(format: "name == %@", currentName)
        
        do {
            let result = try self.container.viewContext.fetch(fetchRequest)
            // 헤당 요청을 담아서 시도함
            
            for data in result as [NSManagedObject] {
                data.setValue(updateName, forKey: PhoneBook.Key.name)
                // 해당 이름에 넣은다음
                try self.container.viewContext.save() // 반영함
                print("데이터 수정 완료")
            }
        } catch {
            print("데이터 수정 실패")
        }
    }
    
    // MARK: Delete 삭제
    func deletDate(name: String) {
        // 삭제할 데이터를 찾기 위한 fetch request 생성
        let fetchRequest = PhoneBook.fetchRequest()
        fetchRequest.predicate = NSPredicate(format: "name == %@", name)
        
        do {
            let result = try self.container.viewContext.fetch(fetchRequest)
            
            for data in result as [NSManagedObject] {
                self.container.viewContext.delete(data) // 찾아서 지우기
            }
            
            try self.container.viewContext.save() // DB에 반영하기
        } catch {
            print("데이터 삭제 실패")
        }
    }
}
profile
iOS 개발

0개의 댓글