首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按数组中的对象分组

按数组中的对象分组
EN

Stack Overflow用户
提问于 2015-12-21 14:23:15
回答 1查看 88关注 0票数 3

我有两个物体。一个称为EstimateItem,另一个称为Part (Part类继承自领域的Object类)。一个EstimateItem可以有多个Part

代码语言:javascript
复制
class EstimateItem {
    var parts: [Part]?
}

每个实例中都有一个具有不同数量的EstimateItemPart数组。

代码语言:javascript
复制
+--------------------------------+---------------------------------+
|         EstimateItem           |            Parts                |
+--------------------------------+---------------------------------+
| Line Item 1 - RnR WDH - Twins  |  Epoxy / Wood for lami          |
| (single)                       |                                 |
|                                |                                 |
| Line Item 2 - RnR WDH - Twins  |  Epoxy / Wood for lami          |
| (double)                       |                                 |
|                                |                                 |
|Line Item 3 - Install sash lock |Epoxy / Wood for lami / Sash lock|
+--------------------------------+---------------------------------+

我需要根据特定的Part对它们进行分组。应该是这样的。

我该怎么做?

当部件连接到单个项目时,我想不出如何做到这一点,所以我尝试将它们全部放置在一个(part: Part, item: EstimateItem)元组数组中。

代码语言:javascript
复制
var groups = [(part: Part, item: EstimateItem)]()
for item in estimateItemsArray {
    if let parts = item.parts {
        for part in parts {
            groups.append((part, item))
        }
    }
}

// Epoxy - RnR WDH - Twins (single)
// Wood for lami - RnR WDH - Twins (single)
// Epoxy - RnR WDH - Twins (double)
// Wood for lami - RnR WDH - Twins (double)
// Epoxy - RnR WDH - Twins (single)
// Wood for lami - RnR WDH - Twins (single)
// Sash lock, traditional - Install sash lock

然后分组。

但我还是被困住了。而且,我觉得我把事情搞得太复杂了,我想知道是否有一种更简单、更快捷的方法来做到这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-21 14:58:45

我想出了一个更好的方法来做这件事:

代码语言:javascript
复制
let parts = Set(estimateItemsArray.flatMap{ $0.parts ?? [] })

let partMap = parts.map { part in
    return (part, estimateItemsArray.filter {
            $0.parts?.indexOf(part) != nil
        }
    )
}

partMap现在包含表单(Part, [EstimateItem])的元组。唯一的要求是Part必须符合Hashable或其他相关内容--在我的测试中,我只允许部分继承NSObject

解释:

  • 创建所有可用部件的数组(Set以确保唯一性)
  • 循环数组映射并返回的元组
    • 实际部分
    • 循环遍历estimateItemsArray,过滤出列表中包含当前部分的项。

完整的测试数据如下所示

代码语言:javascript
复制
/* the now classes, both include some identifier to distinguish them */
class Item {
    var n : String
    var parts : [Part]? = [Part]()
    init(n:String) {
        self.n = n
    }
}

class Part : NSObject {
    var n : String
    init(n:String) {
        self.n = n
    }
}

/* set up the test data */
let item1 = Item(n: "item 1")
let item2 = Item(n: "item 2")
let item3 = Item(n: "item 3")

let part1 = Part(n: "part 1")
let part2 = Part(n: "part 2")
let part3 = Part(n: "part 3")

item1.parts = [part1, part2]
item2.parts = [part1, part3]
item3.parts = [part1, part2, part3]

var arrItems = [item1, item2, item3]

/* actual logic */
let parts = Set(arrItems.flatMap{ $0.parts ?? [] })

let partMap = parts.map { part in
    return (part, arrItems.filter {
            $0.parts?.indexOf(part) != nil
        }
    )
}

/* final output */
partMap.forEach { entry in
    print("part \(entry.0.n)")
    entry.1.forEach {
        print("contains \($0.n)")
    }
}

输出:

第一部分 包含项目1 包含第2项 包含第3项 第3部分 包含第2项 包含第3项 第二部份 包含项目1 包含第3项

如果您不能像我最初那样从NSObject继承,那么让类Part符合Hashable --这是对集合的要求:

代码语言:javascript
复制
class Part : Hashable {
    var n : String
    init(n:String) {
        self.n = n
    }

    var hashValue: Int {
        return n.hashValue // you basically have to provide some kind of logic based on *your* Part object
    }
}

func ==(lhs: Part, rhs: Part) -> Bool {
    return lhs.hashValue == rhs.hashValue
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34397891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档