2015-09-21 9 views
6

配列を列挙したい場合(たとえば、要素のインデックスとその値を一緒に使用する必要があるmap()関数の場合)、enumerate()関数を使用できます。例:今元のインデックスを使用してスライスを列挙するには?

import Foundation 

let array: [Double] = [1, 2, 3, 4] 

let powersArray = array.enumerate().map() { 
    pow($0.element, Double($0.index)) 
} 

print("array == \(array)") 
print("powersArray == \(powersArray)") 

// array == [1.0, 2.0, 3.0, 4.0] 
// powersArray == [1.0, 2.0, 9.0, 64.0] <- As expected 

私は配列からいくつかのサブシーケンスを使用したい場合は、私はsliceを使用することができ、私は元の配列で使用するように、私はちょうど同じインデックスを使用できるようになります(これは、私がループforの中でsubscriptアクセサーを使用する場合に、私が望むものです)。例えば:

let range = 1..<(array.count - 1) 
let slice = array[range] 
var powersSlice = [Double]() 

for index in slice.indices { 
    powersSlice.append(pow(slice[index], Double(index))) 
} 

print("powersSlice == \(powersSlice)") 

// powersSlice == [2.0, 9.0] <- As expected 

しかし、私は、私は全く異なる動作を取得、私は元の配列で行ったようにenumerate().map()アプローチを使用するようにしてください。代わりに、インデックスのsliceの範囲の私は、新しい、0ベースの範囲になるだろう:

let powersSliceEnumerate = slice.enumerate().map() { 
    pow($0.element, Double($0.index)) 
} 

print("powersSliceEnumerate == \(powersSliceEnumerate)") 

// powersSliceEnumerate == [1.0, 3.0] <- Not as expected 

質問はまともな方法があるかどうかである(すなわち、オフセット、または何かを使用して手動で調整なし)を使用してスライスを列挙します独自のインデックスではなく、自動生成された0ベースのインデックスですか?

+1

ないあなたの質問への答えが、あなたは、 '聞かせpowersSlice =スライスを持つforループを置き換えることができます.indices.map {pow(slice [$ 0]、Double($ 0))} ' –

+0

ありがとう、@MartinR。私はあなたの提案を、 'enumerate'が生成したインデックス範囲をオフセットするだけではなく、回避策として念頭に置きます。 – courteouselk

答えて

4

enumerate()n sはゼロから始まる連続Int Sであり(n, elem)対の配列を返します。これは のプロトコル拡張方法SequenceTypeであり、任意のシーケンス は要素に関連付けられたインデックスを必ずしも持っていないので意味があります。

let powersSlice = slice.indices.map { pow(slice[$0], Double($0)) } 

または

let powersSlice = zip(slice.indices, slice).map { pow($1, Double($0)) } 

後者のアプローチは、任意のコレクションのためのプロトコル拡張 方法に一般化することができてあなたが期待する結果を得るでしょう:

extension CollectionType { 
    func indexEnumerate() -> AnySequence<(index: Index, element: Generator.Element)> { 
     return AnySequence(zip(indices, self)) 
    } 
} 

これを(index, elem)ペアのシーケンスを返しますここで、index は、コレクションのインデックスであり、対応する要素elemです。 AnySequenceは、特定のタイプを「非表示にする」ために使用されます。 Zip2Sequence<RangeGenerator<Self.Index>, Self>は、zip() から返されます。

例:スウィフト3用

let powersSliceEnumerate = slice.indexEnumerate().map() { pow($0.element, Double($0.index)) } 
print("powersSliceEnumerate == \(powersSliceEnumerate)") 
// powersSliceEnumerate == [2.0, 9.0] 

更新:

extension Collection { 
    func indexEnumerate() -> AnySequence<(Indices.Iterator.Element, Iterator.Element)> { 
     return AnySequence(zip(indices, self)) 
    } 
} 
+0

優れています。ありがとうございました。 – courteouselk

関連する問題