Быстрый доступ к Odd & amp; Даже элементы внутри массива [дубликат]

Вы хотите использовать REPL - Read → Evaluate → Print Loop.

IRB, например, реализует REPL для языка Ruby.

Вот очень простая реализация REPL:

loop do
  Application::Console.prompt.display
  input = gets.chomp
  command, *params = input.split /\s/

  case command
  when /\Ahelp\z/i
    puts Application::Console.help_text
  when /\Aopen\z/i
    Application::Task.open params.first
  when /\Ado\z/i
    Application::Action.perform *params
  else puts 'Invalid command'
  end
end

\A и \z соответствует началу строки и концу строки соответственно.

7
задан Petravd1994 11 October 2016 в 18:11
поделиться

4 ответа

Вот еще одно возможное решение:

let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] }
let oddA = stride(from: 1, to: masterA.count, by: 2).map { masterA[$0] }

Элементы «выбраны» непосредственно из четных / нечетных позиций в исходном массиве.

Сравнение производительности:

Мой простой, не очень сложный код для бенчмаркинга:

import Swift

let N = 10_000_000
let RUNS = 50

let masterA = (0..<N).map { $0 }

var times = (0.0, 0.0, 0.0, 0.0)
for _ in 1...RUNS {

    // filter+map (dfri)
    do {
        let start = Date()
        let evenA = masterA.enumerated().filter { $0.0 % 2 == 0 }.map{ $0.1 }
        let oddA = masterA.enumerated().filter { $0.0 % 2 != 0 }.map{ $0.1 }
        let time = Date().timeIntervalSince(start)
        times.0 += time
    }

    // flatMap (dfri)
    do {
        let start = Date()
        let evenA = masterA.enumerated().flatMap { $0 % 2 == 0 ? $1 : nil }
        let oddA = masterA.enumerated().flatMap { $0 % 2 != 0 ? $1 : nil }
        let time = Date().timeIntervalSince(start)
        times.1 += time
    }

    // stride+map (me)
    do {
        let start = Date()
        let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] }
        let oddA = stride(from: 1, to: masterA.count, by: 2).map { masterA[$0] }
        let time = Date().timeIntervalSince(start)
        times.2 += time
    }

    // loop (Keiwan)
    do {
        let start = Date()
        var evenA = [Int]()
        var oddA = [Int]()

        for (index, element) in masterA.enumerated() {
            if index % 2 == 0 {
                evenA.append(element)
            } else {
                oddA.append(element)
            }
        }
        let time = Date().timeIntervalSince(start)
        times.3 += time
    }
}

print(N, RUNS)
print(times.0/Double(RUNS), times.1/Double(RUNS), times.2/Double(RUNS), times.3/Double(RUNS))

Результаты: (В MacBook, работающем в режиме деблокирования)

#elements   filter+map  flatMap   stride+map  loop
10,000      0.0001      0.00008   0.00004     0.00004
100,000     0.0016      0.0008    0.0004      0.0004
1,000,000   0.0295      0.0136    0.0090      0.0091
10,000,000  0.3025      0.1332    0.0909      0.1250
16
ответ дан Martin R 15 August 2018 в 22:18
поделиться

Возможно, я не понимаю ваши намерения, но кажется, что вы хотите, чтобы элементы из masterA, имеющие нечетные индексы, должны храниться в oddA, и, наоборот, элементы masterA, которые имеют даже индексы, должны храниться в evenA.

Вы можете добиться этого, отфильтровывая masterA wrt индексы masterA, легко доступные из masterA.enumerated().

let masterA = [4, 5, 2, 1, 7, 8, 1]

let evenA = masterA.enumerated().filter { $0.0 % 2 == 0 }.map{ $0.1 }
let oddA = masterA.enumerated().filter { $0.0 % 2 != 0 }.map{ $0.1 }

print(evenA) // [4, 2, 7, 1]
print(oddA)  // [5, 1, 8]

Как отмечает @Hamish в своем комментарии ниже, мы могли бы использовать compactMap (Swift 3: flatMap) как альтернатива цепным filter и map.

let evenA = masterA.enumerated().compactMap { $0 % 2 == 0 ? $1 : nil }
let oddA = masterA.enumerated().compactMap { $0 % 2 != 0 ? $1 : nil }

Последнее compactMap решение является более кратким, тогда как решение filter ... map, возможно, показывает намерение немного яснее. В этом конкретном соперничестве по сравнению с семантикой я лично предпочел бы решение compactMap.

5
ответ дан dfri 15 August 2018 в 22:18
поделиться
  • 1
    И, конечно, filter и map всегда можно свернуть до flatMap - let evenA = masterA.enumerated().flatMap { $0 % 2 == 0 ? $1 : nil } :) – Hamish 11 October 2016 в 18:38
  • 2
    @Hamish Я не знаю, почему я даже прибегаю к filter, а затем map в эти дни, так как мне всегда напоминают об отказе от решения flatMap xD спасибо! – dfri 11 October 2016 в 18:39
  • 3
    Было бы интересно узнать, какой из них быстрее для больших массивов: filter + map, flatMap или, возможно, let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] }? – Martin R 11 October 2016 в 18:41
  • 4
    10 работает с массивом с 1 000 000 элементов: filter + map: 0.3068 sec, flatMap: 0.127 sec, stride: 0.0967 sec, явный цикл (код Keiwan): 0.0949 сек. - Для 10 000 000 элементов, шаг является самым быстрым. – Martin R 11 October 2016 в 19:01
  • 5
    @dfri: done :-) – Martin R 11 October 2016 в 19:52

Вы можете использовать enumerated(), чтобы получить как индекс, так и значение во время цикла:

for (index, element) in masterA.enumerated() {
    if index % 2 == 0 {
        evenA.append(element)
    } else {
        oddA.append(element)
    }
}

Это будет хранить каждый element из masterA с нечетным индексом в oddA и каждый элемент с четным индексом в evenA.

6
ответ дан Keiwan 15 August 2018 в 22:18
поделиться
  • 1
    @RajanMaheshwari: 0 - четное число, поэтому сохранение элемента с индексом 0 в evenA кажется мне совершенно правильным. – Martin R 11 October 2016 в 18:33
  • 2
    @MartinR Опять же, это зависит от пользователя. Для меня любой элемент в первой позиции является нечетным (значение индекса 0) – Rajan Maheshwari 11 October 2016 в 18:34
  • 3
    @RajanMaheshwari. Кроме того, OP специально запрашивает нечетные индексы ( "...), что все нечетные индексы основного массива будут сохранены в нечетный массив ... & quot; ), который мог бы намекнуть, что OP имеет ту же перспективу в нечетном / четном порядке, что и этот ответ. – dfri 11 October 2016 в 18:37
  • 4
    @Keiwan имеет смысл. Возьми +1 у меня тоже. Просто сделайте небольшое редактирование – Rajan Maheshwari 11 October 2016 в 19:17

Другое решение

Код Swift 3.0

let array = [1,2,3,4,5,6,7,8]
var oddArray = [Int]()
var evenArray = [Int]()

for (index,value) in array.enumerated() {
    if index % 2 == 0 {
        // It is odd because index starts from 0 in array and I am assuming the 0 index as the odd one.
        oddArray.append(value)
    } else {
        evenArray.append(value)
    }
}

Нечетный массив = [1,3,5,7] Даже массив = [2, 4,6,8]

1
ответ дан Rajan Maheshwari 15 August 2018 в 22:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: