2014-10-25 1 views
1

for-in 및 if-let을 하나의 명령문으로 병합 할 수 있습니까?Swift에서 for-in 및 if-let 믹싱

for item in array { 
     if let f = item as? NSDictionary { 
      result.addObject(newFile(f)) 
     } 
    } 

array는 JSON으로 구성되어, 각각의 항목 NSDictionary 여부를 경우 모르겠어요. 내가 확인해야 해.

나는 이런 식으로 뭔가를 찾고 있었다 :

for item as? NSDictionary in array { 
// code 
} 

마찬가지로 파이썬이나 루비.

+2

를? 그것을 더 짧게 만드시겠습니까? 귀하의 코드는 명확하고 읽기 쉽습니다. 당신의 논리를 이해하려고 시도한 후에 다른 개발자에게 더 열심히하지 마십시오. –

+0

만약 그 배열이 사전의 배열이라면 왜 그렇게해야합니까? –

+0

무엇을 확인하려고합니까? 'array'는 어떤 타입입니까? –

답변

3

@nickfalk는 올바른 방향으로 가고 있지만 더 잘할 수 있습니다. 그의 결과는 불행히도 [AnyObject]을 반환합니다. 그러면 newFile으로 전화 할 수는 없지만 나머지 부분은 꽤 얻을 수 있습니다.

원하는 것은 부분지도입니다. 즉, 하나의 lis 요소 중 일부 (그러나 전부는 아닐 수도 있음)를 매핑하고자합니다. 다른 목록으로 이동 (AnyObject에서 File까지 가능). 그래서 선택을위한 규칙과 매핑을위한 규칙이 있어야합니다. 옵션으로 합치 자. 이 함수를 호출 해 보겠습니다. f. 그리고 그 형태는 다음과 같습니다

f: T->U? 

그래서 아마도 UT 변환합니다 마법 기능이있다. 우리는 그것과 매핑하고 싶습니다.

extension Array { 
    func partialMap<U>(f: T->U?) -> [U] { 
    var result = [U]() 
    for x in self { 
     if let u = f(x) { 
     result.append(u) 
     } 
    } 
    return result 
    } 
} 

그래서 지금 우리가 숨긴 모든 불쾌한 돌연변이와 var를하고 이것 저것 아래로 깊은 우리는 그것을 볼 필요가 없습니다 여기서 쉽게 소리. 우리는 "무언가"에서 "어쩌면 다른 것"으로 매핑 함수를 사용하고 "맵핑 할 수있는 무언가"의 목록을 반환하는 함수를 가지고 있습니다.

이제 모든 좋은 불변 및 재사용 :이

let result = array.partialMap { ($0 as? NSDictionary).map(newFile) } 

우와. 그 중간에 map은 무엇입니까? 음, as?NSDictionary?을 반환합니다.map 옵션 인 경우 선택 사항이 None이면 None을 반환하고, 그렇지 않으면 값에 함수를 적용하고 Some에 래핑합니다. 그래서이 모든 일은 AnyObject이며 우리가 원한 것처럼 File?을 반환합니다. 하나 partialMap 나중에 우리는 우리의 대답이 있습니다.

+0

옵션으로 돌아 가지 않고 배열 확장에 호환되지 않는 모든 유형을 필터링하지 않는 것이 좋습니다. 그럼'newFile'을 인수를 풀지 않고 안전하게 호출 할 수 있습니다. – Mohsen

+0

그것이 바로 이것이하는 일입니다. 'newFile'은 옵션이 아닌 NSDictionary로 호출됩니다. 'partialMap'은'[U?]'또는'[U]?'가 아닌'[U]'를 반환합니다. 'mapPartial'을'filter-things-I-can-convert'로 바꾸고 싶다면 그것은 단지'array.partialMap {$ 0 as? NSDictionary}'를 반환하며, 이는 [NSDictionary]를 반환합니다. –

+0

분명히 당신은 또한'array.partialMap {$ 0 as? NSDictionary} .map (newFilter)'를 사용하지만 목록을 두 번 걸어야합니다. 코드가 더 명확 해지면 (그리고 체인이 길어질 수도 있지만) 한 번에 할 수 있습니다. –

1

필터 만 포함 된 배열로 NSArray을 줄이는 것이 목표라면 매우 강력한 도구입니다. 적절한 필터링 기능을 만듭니다

func filterForNSDictionary(object: AnyObject) -> Bool{ 
    return object.isKindOfClass(NSDictionary) 
} 

그리고 단순히 filter 함수로 배열과 기능을 전달

let result = filter(array, filterForNSDictionary) 

@RobNapier는 결과 배열 끝날 위 내 솔루션을 지적 하듯이 유형이 [AnyObject] 인 것은 물론 쉽게 수정할 수 있습니다.

let result = filter(array, filterForNSDictionary) as [NSDictionary] 

배열의 형식을 잘못 지정하면 위험 할 수 있습니다. as [NSString] (... 대부분 선 아래로 당신의 얼굴에 날려 버릴 것 instance9에 대한

롭의 솔루션 물론 순수 멋진 영리되고이 분야에서 절대 초보자 나를 노출하면서 @MattGibson는 완벽한 속기를 제공합니다.

3

나는 아마 같은 뭔가를 갈 것 :

let result = array.filter() { $0 is NSDictionary } 

당신이있는 NSDictionary 배열로 result이 필요하면 그냥 캐스팅 할 수 있습니다 무엇에 대한

let result = array.filter() { $0 is NSDictionary } as [NSDictionary]