2017-05-21 2 views
1

2 개의 어레이가 있습니다. 첫 번째 배열 안에 두 번째 배열에서 제거 할 이름 목록이 있습니다.이름 배열을 기준으로 배열을 필터링하는 방법은 무엇입니까?

var arrayNames = ["apple", "apricot", "cucumber"] 

두 번째 배열은 사용자 정의 structs의 배열은 다음과 같습니다 :

첫 번째 배열은 단순히 문자열의 배열입니다

struct fruitsData { 
var name: String? 
} 

var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "cucumber"), fruitsData(name: "brinjal")] 

그래서이 데이터 만 들어있는 배열을 얻을 수있는 방법 :

var finalData = [fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "brinjal")] 

arrayNames의 이름이 있습니까?

+0

우리의 답변에 대한 귀하의 의견을 볼 좋을 것이다 사용할 수 있습니다. –

답변

0

나는 그래서 그것을 확인할 수는 없지만,이 트릭을해야 전화입니다

이 작업을 수행하는 몇 가지 방법이 있습니다
secondArray.filter { !firstArray.contains($0.name) } 
1

:

  • 은 가장 좋은 방법은 filter 방법을 사용하는 것입니다.

    var arrayNames = ["apple", "apricot", "cucumber"] 
    var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "cucumber"), fruitsData(name: "brinjal")] 
    
    secondArray = secondArray.filter({$0.name != nil && !arrayNames.contains($0.name!)}) 
    
  • var arrayNames = ["apple", "apricot", "cucumber"] 
    var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "cucumber"), fruitsData(name: "brinjal")] 
    var helperArray = [fruitsData]() 
    
    for fruit in secondArray { 
    
        if fruit.name != nil && !arrayNames.contains(fruit.name!){ 
         helperArray.append(fruit) 
        } 
    
    } 
    
    secondArray = helperArray 
    

위의 이름이 arrayNames에 포함되어 secondArray에서 모든 요소를 ​​삭제합니다 : 당신은 가독성을 위해 효율성을 희생하려는 경우 (10)는 양자 택일로, 당신은 헬퍼 배열 나란히 for-in 루프를 사용할 수 있습니다 . Map, Filter and Reduce에 익숙해 져야합니다.

1

finalDatasecondArrayarrayNames을 제외하면 여기에서 얻을 수 있습니다. .

var finalData = secondArray.filter { !arrayNames.contains($0.name!)} 
0

주어진 배열 및 일부 조건부에서 부분 집합 배열을 만들려는 자연스러운 접근 방식은 filter입니다. FruitsData 구조체의 nameOptional이므로 arrayNames 목록의 비 Optional 이름과 비교하기 전에 언 래핑 (unwrap)해야합니다. map(_:) 방법을 사용하여 Optional을 처리하고 선택 체인을 사용하여 nil- 평가 name 사례.

예 : 전자는 수로 StringHashable을 준수하기 때문에

// example setup 
struct FruitsData { 
    var name: String? 
} 

let arrayNames = ["apple", "apricot", "cucumber"] 

let secondArray = [ 
    FruitsData(name: "apple"), FruitsData(name: "apricot"), 
    FruitsData(name: "mango"), FruitsData(name: "grapes"), 
    FruitsData(name: "tomato"), FruitsData(name: "lichi"), 
    FruitsData(name: "cucumber"), FruitsData(name: "brinjal") 
] 

// filter 'secondArray' based on the non-existance of an 
// associated fruit name in the 'arrayNames' list 
let finalData = secondArray.filter { 
    $0.name.map { fruitName in !arrayNames.contains(fruitName) } ?? true 
} 

, 당신은 또한 과일 이름의 목록을 제외 할시키는 것을 고려할 수 있습니다 (arrayNames), Array보다는 Setcontains { ... }을 적용 할 때 O(1) 조회를 수행하십시오. 예 ::


당신은 또한 nil 가치 name 특성을 가지고 secondArrayFruitsData 인스턴스를 필터링하려는 경우

let removeNames = Set(arrayNames) 
let finalData = secondArray.filter { 
    $0.name.map { fruitName in !removeNames.contains(fruitName) } ?? true 
}          /* ^^^^^^^^- O(1) lookup */ 
, 당신은 단순히 ... ?? false에 위의 ... ?? true 술어 부분 수 있습니다 다음 filter 작업은 다음 걸러 모든 FruitsData 인스턴스의 namenil이거나 arrayNames입니다. 이름이 빈 문자열이 될 것으로 예상되지 않는 경우

// ... filter out also FruitsData instances with 'nil' valued 'name' 
let removeNames = Set(arrayNames) 
let finalData = secondArray.filter { 
    $0.name.map { fruitName in !removeNames.contains(fruitName) } ?? false 
} 
+0

당신의 솔루션은 모든 FruitsData를 리턴 할 것이다. name == nil 일 것이다. – user3441734

+0

@ user3441734 나는 OP가'name '이 비 선택적'[String]'배열'arrayNames'에도 존재하는'FruitsData' 인스턴스 만'FruitsData' 배열로부터 필터링해야한다고 믿습니다. 이것은'name' 인스턴스를 갖는'FruitsData' 인스턴스가 필터링 된'FruitsData' 배열에 보관 될 것으로 기대되는 결과와 일치합니다. 반면에,'nil' 객체가 제거되어야한다면 (OP에 의해 지정되지 않았다면), 그것은 단지'... ?? true'와'... ?? 위의'filter '에 대한 술어에서'false'를 사용한다. – dfri

+0

예, 작동합니다. 안타깝게도 역함수는 쉽지 않으므로 별명없이 데이터를 처리하는 방법을 결정해야합니다. – user3441734

0

, 당신은

let arrayNames = ["apple"] 

struct fruitsData { 
    var name: String? 
} 
var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData()] 

// [__lldb_expr_98.fruitsData(name: Optional("apple"))] 
let flt1 = secondArray.filter { arrayNames.contains($0.name ?? "") } 

// [__lldb_expr_87.fruitsData(name: Optional("apricot")), __lldb_expr_87.fruitsData(name: nil)] 
let flt2 = secondArray.filter { !arrayNames.contains($0.name ?? "") } 
관련 문제