17370845950

合并数组中基于键值的对象

本文旨在提供一种解决方案,用于合并数组中具有相同键值的对象。通过使用 groupBy 和 flatMap 等函数,我们可以将具有相同 categoryId 的对象合并成一个对象,并将它们的 addons 列表合并成一个单一的列表。文章将提供详细的代码示例,帮助读者理解和实现这一过程。

假设我们有一个包含多个对象的数组,每个对象都包含一个 categoryId 和一个 addons 列表。我们的目标是将具有相同 categoryId 的对象合并成一个对象,并将它们的 addons 列表合并成一个单一的列表。

例如,我们有以下数组:

[
  {
    "addons": [
      {
        "addonId": "Addon_5035fac357f446fb8b4fcff45d2e36e5",
        "addonIdentifier": "Gherkin",
        "addonQuantity": 1,
        "subTotal": 0.99,
        "addonType": "EXTRAS"
      }
    ],
    "categoryId": "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303",
    "categoryIdentifier": "Extra 1"
  },
  {
    "addons": [
      {
        "addonId": "Addon_700a1458fae54ba9b3e148da709eea4a",
        "addonIdentifier": "Hash Brown",
        "addonQuantity": 1,
        "subTotal": 0.99,
        "addonType": "EXTRAS"
      }
    ],
    "categoryId": "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303",
    "categoryIdentifier": "Extra 1"
  },
  {
    "addons": [
      {
        "addonId": "Addon_f4408295adb14723aa22a3a7e645a7a7",
        "addonIdentifier": "Cheese",
        "addonQuantity": 1,
        "subTotal": 0.99,
        "addonType": "EXTRAS"
      }
    ],
    "categoryId": "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303",
    "categoryIdentifier": "Extra 1"
  }
]

我们希望将其转换为以下格式:

[
  {
    "addons": [
      {
        "addonId": "Addon_5035fac357f446fb8b4fcff45d2e36e5",
        "addonIdentifier": "Gherkin",
        "addonQuantity": 1,
        "subTotal": 0.99,
        "addonType": "EXTRAS"
      },
      {
        "addonId": "Addon_700a1458fae54ba9b3e148da709eea4a",
        "addonIdentifier": "Hash Brown",
        "addonQuantity": 1,
        "subTotal": 0.99,
        "addonType": "EXTRAS"
      },
      {
        "addonId": "Addon_f4408295adb14723aa22a3a7e645a7a7",
        "addonIdentifier": "Cheese",
        "addonQuantity": 1,
        "subTotal": 0.99,
        "addonType": "EXTRAS"
      }
    ],
    "categoryId": "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303",
    "categoryIdentifier": "Extra 1"
  }
]

以下是一些实现此目标的示例代码:

方法一:使用 groupBy 和 mapValues

此方法首先使用 groupBy 函数按 categoryId 对对象进行分组,然后使用 mapValues 函数将每个组中的 addons 列表合并成一个单一的列表。

data class Item(
    val addons: List,
    val categoryId: String,
    val categoryIdentifier: String
)

data class Addon(
    val addonId: String,
    val addonIdentifier: String,
    val addonQuantity: Int,
    val subTotal: Double,
    val addonType: String
)

fun mergeItems(items: List): Map {
    return items.groupBy({ it.categoryId }, { it.addons })
        .mapValues { (_, addonLists) -> addonLists.flatten() }
}

// 示例用法
fun main() {
    val items = listOf(
        Item(listOf(Addon("Addon_5035fac357f446fb8b4fcff45d2e36e5", "Gherkin", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1"),
        Item(listOf(Addon("Addon_700a1458fae54ba9b3e148da709eea4a", "Hash Brown", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1"),
        Item(listOf(Addon("Addon_f4408295adb14723aa22a3a7e645a7a7", "Cheese", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1")
    )

    val mergedItems = mergeItems(items)
    println(mergedItems)
}

方法二:使用 flatMap 和 groupBy

此方法首先使用 flatMap 函数将每个 Item 对象转换为一个 (categoryId, Addon) 对的列表,然后使用 groupBy 函数按 categoryId 对这些对进行分组。

fun mergeItems2(items: List): Map {
    return items.flatMap { item ->
        item.addons.map { addon -> item.categoryId to addon }
    }.groupBy({ it.first }, { it.second })
}

// 示例用法
fun main() {
    val items = listOf(
        Item(listOf(Addon("Addon_5035fac357f446fb8b4fcff45d2e36e5", "Gherkin", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1"),
        Item(listOf(Addon("Addon_700a1458fae54ba9b3e148da709eea4a", "Hash Brown", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1"),
        Item(listOf(Addon("Addon_f4408295adb14723aa22a3a7e645a7a7", "Cheese", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1")
    )

    val mergedItems = mergeItems2(items)
    println(mergedItems)
}

方法三:使用 fold 和 mutableMapOf

此方法使用 fold 函数创建一个可变映射,并将具有相同 categoryId 的 addons 列表添加到该映射中。

fun mergeItems3(items: List): MutableMap {
    return items.fold(mutableMapOf()) { groups, item ->
        groups.apply {
            getOrPut(item.categoryId) { mutableListOf() }
            .addAll(item.addons)
        }
    }
}

// 示例用法
fun main() {
    val items = listOf(
        Item(listOf(Addon("Addon_5035fac357f446fb8b4fcff45d2e36e5", "Gherkin", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1"),
        Item(listOf(Addon("Addon_700a1458fae54ba9b3e148da709eea4a", "Hash Brown", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1"),
        Item(listOf(Addon("Addon_f4408295adb14723aa22a3a7e645a7a7", "Cheese", 1, 0.99, "EXTRAS")), "Addon_Cate_1a7bacd1a07b40ceb7d5d3a2229fb303", "Extra 1")
    )

    val mergedItems = mergeItems3(items)
    println(mergedItems)
}

注意事项

  • 以上代码示例使用了 Kotlin 语言。
  • 这些方法假设 categoryId 是用于合并对象的唯一键。如果需要使用多个键进行合并,则需要修改代码。
  • 这些方法返回的是不可变集合。如果需要返回可变集合,则需要使用 toMutableList() 或 toMutableMap() 函数。

总结

本文提供了一种解决方案,用于合并数组中具有相同键值的对象。通过使用 groupBy 和 flatMap 等函数,我们可以将具有相同 categoryId 的对象合并成一个对象,并将它们的 addons 列表合并成一个单一的列表。希望这些代码示例能够帮助读者理解和实现这一过程。