最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Remove duplicate objects from JSON array in Java or Kotlin - Stack Overflow

programmeradmin1浏览0评论

I'm trying to figure out how to remove duplicate classInformation from schoolInformation if the below conditions are matched:

  • classInformation.teacherPercentage and classInformation.teachInfo.id are the same
  • classInformation.studentPercentage and classInformation.studentInfo.id, classInformation.studentInfo.style, classInformation.studentInfo.graduationYear are the same

JSON:

{
  "schoolInfomration": [
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2028
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10019",
            "name" : "test2"
          }
        }
      ]
    },
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2028
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10019",
            "name" : "test1"
          }
        }
      ]
    },
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2023
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10018",
            "name": "test3"
          }
        }
      ]
    }
  ]
}

Output:

{
  "schoolInfomration": [
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2028
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10019",
            "name" : "test2"
          }
        }
      ]
    },
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2023
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10018",
            "name": "test3"
          }
        }
      ]
    }
  ]
}

Data Classes:


data class Root(
    val schoolInfomration: List<SchoolInfomration>,
)

data class SchoolInfomration(
    val classInformation: List<ClassInformation>,
)

data class ClassInformation(
    val studentPercentage: Long?,
    val studentInfo: StudentInfo?,
    val teacherPercentage: Long?,
    val teacherInfo: TeacherInfo?,
)

data class StudentInfo(
    val id: Long,
    val style: Long,
    val graduationYear: Long,
)

data class TeacherInfo(
    val id: String,
    val name: String,
)

I'm trying to figure out how to remove duplicate classInformation from schoolInformation if the below conditions are matched:

  • classInformation.teacherPercentage and classInformation.teachInfo.id are the same
  • classInformation.studentPercentage and classInformation.studentInfo.id, classInformation.studentInfo.style, classInformation.studentInfo.graduationYear are the same

JSON:

{
  "schoolInfomration": [
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2028
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10019",
            "name" : "test2"
          }
        }
      ]
    },
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2028
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10019",
            "name" : "test1"
          }
        }
      ]
    },
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2023
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10018",
            "name": "test3"
          }
        }
      ]
    }
  ]
}

Output:

{
  "schoolInfomration": [
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2028
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10019",
            "name" : "test2"
          }
        }
      ]
    },
    {
      "classInformation": [
        {
          "studentPercentage": 50,
          "studentInfo": {
            "id": 4,
            "style": 3,
            "graduationYear": 2023
          }
        },
        {
          "teacherPercentage": 50,
          "teacherInfo": {
            "id": "10018",
            "name": "test3"
          }
        }
      ]
    }
  ]
}

Data Classes:


data class Root(
    val schoolInfomration: List<SchoolInfomration>,
)

data class SchoolInfomration(
    val classInformation: List<ClassInformation>,
)

data class ClassInformation(
    val studentPercentage: Long?,
    val studentInfo: StudentInfo?,
    val teacherPercentage: Long?,
    val teacherInfo: TeacherInfo?,
)

data class StudentInfo(
    val id: Long,
    val style: Long,
    val graduationYear: Long,
)

data class TeacherInfo(
    val id: String,
    val name: String,
)
Share Improve this question edited Mar 18 at 15:12 dani-vta 7,5357 gold badges49 silver badges65 bronze badges asked Mar 18 at 14:01 SamiSami 6069 silver badges23 bronze badges 2
  • I think it depends on how you exactly parse the response. If you for example have well-defined kotlin data classes that the json is turned into so that schoolInformation becomes a List<ClassInformation> for example then just removing duplicates should work by just calling distinct() on the list I believe since they would actually be considered identical ClassInformation instances if I'm not mistaken – Ivo Commented Mar 18 at 14:48
  • @Ivo, I updated the question with the data classes. – Sami Commented Mar 18 at 15:07
Add a comment  | 

1 Answer 1

Reset to default 6

You could use following stack:

  • ObjectMapper to deserialize
  • distinctBy to remove duplicates
  • copy(fieldToChange = ...) to change only required fields and copy the rest
@Test
fun `remove duplicates by fields of objects in the inner collection`() {
    val mapper = ObjectMapper().registerKotlinModule()
    val input = mapper.readValue<Root>(inputString)

    val withoutDuplicates = input.copy(
        schoolInfomration = input.schoolInfomration
            .distinctBy { schoolInfomration ->
                schoolInfomration.classInformation
                    .map { classInformation ->
                        // use list to take into account order of classInformation's fields
                        listOf(
                            classInformation.teacherPercentage,
                            classInformation.teacherInfo?.id,
                            classInformation.studentPercentage,
                            classInformation.studentInfo?.id,
                            classInformation.studentInfo?.graduationYear,
                            classInformation.studentInfo?.style
                        )
                    }
                    // use set in order to ignore order of classInformation
                    .toSet()
            }
    )

    val output = mapper.readValue<Root>(outputString)
    assertEquals(output, withoutDuplicates)
}
  • inputString - a string with your input
  • outputString - a string with your output
发布评论

评论列表(0)

  1. 暂无评论