如何附加到数组的某个部分? [[]]

时间:2016-08-30 12:40:07

标签: ios iphone swift uitableview tableview

我有一个数组数组theMealIngredients = [[]]

我正在从当前餐中创建一个newMeal,我基本上将所有选中标记的成分从右侧部分复制到其中并从桌面视图中排成一行。但是,当我使用append时,它显然不知道哪个部分进入,因为数组是多维的。它一直告诉我把它投射为NSArray,但这不是我想要做的,我不认为。

我正在使用的当前行是:

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

1 个答案:

答案 0 :(得分:4)

您应该重新建模数据以符合其含义,然后从中提取您的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)

我们不必担心将每种成分放入哪个部分进行复制。我们只是把所有的成分都扔进了餐点,然后让它们整理出来。

其中一些代码效率非常低(它会多次重新计算某些内容)。如果成分列表可能很长(但它们可能不是),那将是一个问题,并且可以根据需要通过缓存结果或重新设计膳食的内部实施细节来进行优化。但是从一个清晰的数据模型开始,可以使代码简单明了,而不是在调用代码的嵌套数组中丢失。

多维数组在Swift中使用非常具有挑战性,因为它们并不是真正的多维数组。它们只是数组的数组。这意味着每一行都可以有不同数量的列,这是人们在给定行的末端运行时崩溃的常见原因。