有没有办法从子数组中读取?

Posted

技术标签:

【中文标题】有没有办法从子数组中读取?【英文标题】:Is there a way of reading from sub arrays? 【发布时间】:2021-04-21 21:26:07 【问题描述】:

我目前正在构建一个 ios 应用程序,该应用程序使用 Google Firestore 存储用户添加的产品。添加的每个产品都连接成一个用户特定的“产品”数组(如下所示 - 尽管它们有不同的数字,但它们是同一数组的一部分,但在 UI 中被 Google 分开以更清楚地显示每个单独的子数组)

我使用以下语法从数据库中“产品”字段的第一个子数组中返回数据

  let group_array = document["product"] as? [String] ?? [""]
     if  (group_array.count) == 1 
            
         let productName1 = group_array.first ?? "No data to display :("`
                        
         self.tableViewData =
                           [cellData(opened: false, title: "Item 1", sectionData: [productName1])]

                            

返回格式如下:

产品名称:1,上市价格:3,简要说明:4,产品网址:2,上市有效期至:21/04/2021 10:22:17

但是,我尝试查询此子数组的每个单独部分,例如,我可以返回“产品名称:1”而不是整个子数组。由于let productName1 = group_array.first 用于返回第一个子数组,我尝试let productName1 = group_array.first[0] 尝试返回此子数组中的第一个值,但是我收到以下错误:

无法根据成员“first”推断上下文基础

所以我的问题是,参考我的数据库中的图像(在我的问题的顶部),如果我只想从示例子数组中返回“产品名称:1”,这是否可能,如果可以,我将如何提取它?

【问题讨论】:

在第一张图片 product 中,这是一个包含 2 个项目的数组,其中每个项目只是一个长字符串,如 Product Name: 1, Listing Price: 3, A brief description: 4, Product URL: 2, Listing active until: 21/04/2021 10:22:17 嗨,bxod,我将如何从字符串中读取并返回“产品名称:(值)”?我会使用子字符串吗? 我的问题的答案是肯定的吗?您在帖子中提到的“子数组”是什么? 您的问题的答案是肯定的。子数组是引用,因此数组中的每个部分(例如,“0”被称为子数组),然后它们作为字符串返回。 :) 好的,你的意思是下标,不是子数组。 【参考方案1】:

我会重新考虑将产品存储为需要解析的长字符串,因为我怀疑存在更有效且不易出错的模式。然而,这种模式是 JSON 的工作方式,所以如果您想以这种方式组织产品数据,让我们继续使用它来解决您的问题。

let productRaw = "Product Name: 1, Listing Price: 3, A brief description: 4, Product URL: 2, Listing active until: 21/04/2021 10:22:17"

您可以做的第一件事是将字符串解析为组件数组:

let componentsRaw = productRaw.components(separatedBy: ", ")

结果:

["Product Name: 1", "Listing Price: 3", "A brief description: 4", "Product URL: 2", "Listing active until: 21/04/2021 10:22:17"]

然后你可以使用子字符串搜索这个数组,但是为了效率,我们把它翻译成字典以便于访问:

var product = [String: String]()

for component in componentsRaw 
    let keyVal = component.components(separatedBy: ": ")

    product[keyVal[0]] = keyVal[1]

结果:

["Listing active until": "21/04/2021 10:22:17", "A brief description": "4", "Product Name": "1", "Product URL": "2", "Listing Price": "3"]

然后简单地通过它的键找到产品:

if let productName = product["Product Name"] 
    print(productName)
 else 
    print("not found")

这里有很多警告。产品字符串必须始终保持一致,因为逗号和冒号必须始终遵循这种严格的格式。如果产品名称有冒号和逗号,这将不起作用。您可以对其进行修改以处理这些情况,但它很快就会变成一碗意大利面,这也是我建议完全使用不同数据模式的原因。您还可以探索将数组转换为字典的其他方法,例如使用 reducegrouping,但存在大 O 性能警告。但如果这是您想走的路,这将是一个很好的起点。

综上所述,如果您真的想使用此数据模式,请考虑在产品字符串中添加分隔符。例如,自定义分隔符将大大减少处理边缘情况的需要:

let productRaw = "Product Name: 1**Listing Price: 3**A brief description: 4**Product URL: 2**Listing active until: 21/04/2021 10:22:17"

使用像** 这样的分隔符,值可以包含逗号而无需担心。但是为了完全安全(和效率),我会添加第二个分隔符,以便值可以包含逗号或冒号:

let productRaw = "name$$1**price$$3**description$$4**url$$2**expy$$21/04/2021 10:22:17"

使用此字符串,您可以更安全地通过** 解析组件,并通过$$ 解析键中的值。它看起来像这样:

let productRaw = "name$$1**price$$3**description$$4**url$$2**expy$$21/04/2021 10:22:17"
let componentsRaw = productRaw.components(separatedBy: "**")
var product = [String: String]()

for component in componentsRaw 
    let keyVal = component.components(separatedBy: "$$")
    product[keyVal[0]] = keyVal[1]


if let productName = product["name"] 
    print(productName)
 else 
    print("not found")

【讨论】:

你是英雄。非常感谢!

以上是关于有没有办法从子数组中读取?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据查询从子文档数组中更新子文档字段?

在 Flutter 中,当子组件的 build 方法中没有回调时,如何从子组件中读取数据?

从子组件中过滤数组数据表

返回一个整数数组中最大子数组的和

从子组件过滤数组数据表

如何在反应中将数组从子组件发送到父组件?