找到你要的答案

Q:Iterate over all elements in the array in order starting given index

Q:遍历数组中的所有元素,从给定的索引

Say, I have an array let array = [ "foo", "bar", "baz", "foobar", "qux" ] and an index 3 inside this array. I want to iterate all elements in the array in a following order foobar (element at index 3), qux (at index 4), foo (at index 0, etc.), bar, baz.

Not so elegant solution would look like this:

for index in givenIndex ..< array.endIndex {
  // do some work with array[index]
}

for index in array.startIndex ..< givenIndex {
  // do the same work with array[index]
}

Is there a more elegant solution?

说,我有一个数组让阵= [“foo”、“酒吧”、“巴兹”、“foobar”、“qux”]和3指数在这个阵列。我想重申所有元素在数组顺序为foobar(索引为3元),qux(在指数4)、foo(索引0,等),酒吧,巴兹。

不那么优雅的解决方案看起来像这样:

for index in givenIndex ..< array.endIndex {
  // do some work with array[index]
}

for index in array.startIndex ..< givenIndex {
  // do the same work with array[index]
}

有更优雅的解决方案吗?

answer1: 回答1:

An extension and the % operator should work:

extension CollectionType where Index : IntegerType, Index.Distance == Index {
  func offset(by: Index) -> [Generator.Element] {
    guard by >= 0 else { return offset(by+count) }
    return (by..<(by+count))
      .map { i in self[i % count + startIndex] }
  }
}


let array = [ "foo", "bar", "baz", "foobar", "qux" ]

array.offset( 1) // ["foobar", "qux", "foo", "bar", "baz"]
array.offset(-1) // ["qux", "foo", "bar", "baz", "foobar"]

let s = array.suffixFrom(2) // ["baz", "foobar", "qux"]

s.offset( 1) // ["foobar", "qux", "baz"]
s.offset(-1) // ["qux", "baz", "foobar"]

扩展和%运算符应工作:

extension CollectionType where Index : IntegerType, Index.Distance == Index {
  func offset(by: Index) -> [Generator.Element] {
    guard by >= 0 else { return offset(by+count) }
    return (by..<(by+count))
      .map { i in self[i % count + startIndex] }
  }
}


let array = [ "foo", "bar", "baz", "foobar", "qux" ]

array.offset( 1) // ["foobar", "qux", "foo", "bar", "baz"]
array.offset(-1) // ["qux", "foo", "bar", "baz", "foobar"]

let s = array.suffixFrom(2) // ["baz", "foobar", "qux"]

s.offset( 1) // ["foobar", "qux", "baz"]
s.offset(-1) // ["qux", "baz", "foobar"]
answer2: 回答2:

To keep from repeating your work block you could convert your ranges to arrays and add them:

let givenIndex = 3
let array = [ "foo", "bar", "baz", "foobar", "qux" ]

for index in Array(givenIndex ..< array.endIndex) + Array(0 ..< givenIndex) {
    // do some work with array[index]
    print(array[index])
}

Alternative Answer

Since elegant is in the eye of the beholder, another way to avoid repeating your work block is to put your ranges in an array and then select them in order before iterating over them:

for range in [givenIndex ..< array.endIndex, 0 ..< givenIndex] {
    for index in range {
        // do some work with array[index]
        print(array[index])
    }
}

为了避免重复工作块,可以将范围转换为数组并将其添加到数组中:

let givenIndex = 3
let array = [ "foo", "bar", "baz", "foobar", "qux" ]

for index in Array(givenIndex ..< array.endIndex) + Array(0 ..< givenIndex) {
    // do some work with array[index]
    print(array[index])
}

可供选择的答案

因为优雅是在旁观者的眼睛,另一种方式来避免重复你的工作就是把你的范围块数组中,然后选择他们为他们之前的迭代:

for range in [givenIndex ..< array.endIndex, 0 ..< givenIndex] {
    for index in range {
        // do some work with array[index]
        print(array[index])
    }
}
arrays  swift