2016-08-30 1 views
1

У меня есть массив массивов, theMealIngredients = [[]]Как добавить в раздел массива? [[]]

Я создаю newMeal из текущей еды, и я в основном копируя все ингредиенты в отмеченном него из правой части и ряд из Tableview. Однако, когда я использую append, он, очевидно, не знает, какой раздел следует включать, поскольку массив является многомерным. Он продолжает рассказывать мне, чтобы он использовал его как NSArray, но это не то, что я хочу сделать, я не думаю.

текущей строки я использую:

newMeal.theMealIngredients.append((selectedMeal!.theMealIngredients[indexPath.section][indexPath.row]) 
+0

Сначала вы должны получить раздел из своего источника. Поместите этот массив (массив строк в этом разделе) в переменную. Затем добавьте еду к этой переменной. А затем замените этот раздел в своем источнике на его собственный индекс. – pedrouan

+0

Если вы только копируете выбранные ингредиенты, как вы планируете работать над разделами, если ничего не выбрано из раздела? Итак, если что-то из разделов 0, 2 и 3 выбрано, должны ли они быть в 0, 2 и 3 копии или в 0, 1 и 2?Понимание того, что представляют собой эти «разделы», и то, как вы сейчас выполняете цикл, вероятно, будет полезно здесь. Не совсем понятно, почему есть разделы и как они относятся к еде. Является ли еда состоящей из блюд, которые состоят из ингредиентов? –

+0

@RobNapier Привет, Роб, спасибо за ответ. Таким образом, в основном каждый прием пищи получает такие ингредиенты, как курица-паста, это еда. Мягкие ингредиенты = [[цыпленок], [макаронные изделия], []], а затем разделы, которые [[мясо], [углеводы]] и т. Д., Но тогда есть дополнительные ингредиенты, такие как как грибы, перец, шпинат, и я хочу, чтобы люди могли выбирать эти или нет, чтобы они оставались в правой части копии. Извините, я должен был быть более ясным в начале. –

ответ

3

Вы должны повторно модель данных, чтобы соответствовать его значение, а затем извлечь ваш TableView от этого. Таким образом, вы можете намного легче работать с данными, не беспокоясь о особых потребностях в отображении данных. Из вашего описания, у вас есть тип, Meal который имеет [Ingredient]:

struct Meal { 
    let name: String 
    let ingredients: [Ingredient] 
} 

(Ничего этого не было проверено, но оно должно быть довольно близко, чтобы исправить это все в Swift 3; Swift 2,2 очень похожа. .)

Ingredient имеет имя и вид (мясо, углеводы и т.д.):

struct Ingredient { 
    enum Kind: String { 
     case meat 
     case carbs 
     var name: String { return self.rawValue } 
    } 
    let kind: Kind 
    let name: String 
} 

Теперь мы можем думать о вещах в терминах разделов, а не еды и ингридиентов и строк. Но, конечно, нам нужны разделы и строки для табличных представлений. Нет проблем. Добавьте их.

extension Meal { 
    // For your headers (these are sorted by name so they have a consistent order) 
    var ingredientSectionKinds: [Ingredient.Kind] { 
     return ingredients.map { $0.kind }.sorted(by: {$0.name < $1.name}) 
    } 

    // For your rows 
    var ingredientSections: [[Ingredient]] { 
     return ingredientSectionKinds.map { sectionKind in 
      ingredients.filter { $0.kind == sectionKind } 
     } 
    } 
} 

Теперь мы можем легко захватить ингредиент для любого заданного индекса пути, и мы можем реализовать требование копирования на основе индекса путей:

extension Meal { 
    init(copyingIngredientsFrom meal: Meal, atIndexPaths indexPaths: [IndexPath]) { 
     let sections = meal.ingredientSections 
     self.init(name: meal.name, ingredients: indexPaths.map { sections[$0.section][$0.row] }) 
    } 
} 

Теперь мы можем сделать все в одной строке вызывающего кода в контроллере табличного:

let newMeal = Meal(copyingIngredientsFrom: selectedMeal, 
        atIndexPaths: indexPathsForSelectedRows) 

Мы не должны беспокоиться о том, какой раздел поместить каждый ингредиент в для копирования. Мы просто бросаем все ингредиенты в Пищу и позволяем им сортироваться позже.

Некоторые из этого кода очень неэффективны (он многократно переваривает некоторые моменты). Это будет проблемой, если списки ингредиентов могут быть длинными (но они, вероятно, нет), и могут быть оптимизированы, если необходимо, путем кэширования результатов или перепроектирования внутренних деталей реализации Meal. Но, начиная с четкой модели данных, код остается простым и простым, а не теряется во вложенных массивах в вызывающем коде.

Многомерные массивы очень сложны в использовании в Swift, потому что они не очень многомерны. Это всего лишь массивы массивов. Это означает, что каждая строка может иметь разное количество столбцов, что является общим источником сбоев в ошибках, когда люди бегут с концов данной строки.

+0

Большое вам спасибо за помощь! Это абсолютно невероятно, и я вижу, что ты вложил в это много усилий, поэтому я очень ценю это. Я довольно новичок, поэтому очень приятно иметь такое полезное сообщество. Я просто быстро задавался вопросом об этой последней строке, self.init (components: indexPaths.map {разделы [$ 0.section] [$ 0.row]}). Я получаю сообщение об ошибке «Не могу вызвать Meal.init с типом списка аргументов» (ингредиенты: [Ингредиент]]) –

+0

Я забыл передать имя функции init. –

+0

Извините, пожалуйста, вы покровительствовали мне и объясняли, как я сделайте это? @RobNapier –

 Смежные вопросы

  • Нет связанных вопросов^_^