Home > Back-end >  how to set values to value of data class type with val attributes?
how to set values to value of data class type with val attributes?

Time:09-17

I'm sorry for this question name. So I have a data class:

data class Day(
    val date: Int = 0,
    val night: Time? = null,
    val morning: Time? = null,
    val noon: Time? = null,
    val evening: Time? = null,
)

I'm making variable with type of this class and i need to set values to this variable:

val days = ArrayList<Day>()
        val listOfDays = this
            .groupBy { it.getDayOfMonth() }
            .map { WeatherForDay(it.value) }
            .take(FIVE_DAYS_FORECAST)

        listOfDays.forEach {
            val day = Day()
            var weather: WeatherList
            for (hour in it.weather.indices) {
                weather = it.weather[hour]
                val time = Time(
                    weather.main.temp,
                    weather.main.feels_like,
                    weather.wind.speed,
                    weather.wind.gust,
                    weather.wind.deg,
                    weather.main.pressure,
                )

                when (it.weather[hour].getTime()) {
                    NIGHT_DAYTIME -> day.night = time
                    MORNING_DAYTIME -> day.morning = time
                    DAY_DAYTIME -> day.noon = time
                    EVENING_DAYTIME -> day.evening = time
                }
                day.date = weather.dt
            }
            days.add(day)

But i can't because my attributes in data class are values. And i need it to be values. So how can i make this code in a right style with val?

CodePudding user response:

You may use the day.copy(night = time) method that exists for each data class. If you don't want new allocations the only way that I see is to define local variables for each data class property and set them in the loop, and then, in the end of an iteration, create the instance of the data class on the base of these variables.

CodePudding user response:

Rearrange your code so you only instantiate the class when you have all the parameters you need.

val listOfDays = this
  .groupBy { it.getDayOfMonth() }
  .map { WeatherForDay(it.value) }
  .take(FIVE_DAYS_FORECAST)

val days = listOfDays.map { listOfDaysDay ->
  val date = listOfDaysDay.weather.firstOrNull()?.dt ?: 0
  val timeItemByTime = listOfDaysDay.weather
    .associateBy { it.getTime() }
    .map { with (it) {
      Time(
        main.temp
        main.feels_like,
        wind.speed,
        wind.gust,
        wind.deg,
        main.pressure
      )
    } }
  Day(
    date, 
    timeItemByTime[NIGHT_DAYTIME],
    timeItemByTime[MORNING_DAYTIME],
    timeItemByTime[DAY_DAYTIME],
    timeItemByTime[EVENING_DAYTIME]
  )
}

I might have some errors above. It's kind of hard to keep your types straight because of your naming scheme. You have a "listOfDays" that is not a list of your Day class but of some other entity. And you have a class named Time that isn't a time but just a bunch of concurrent weather conditions. And you have something else called "time" that is apparently String or Int constants that actually do represent time.

And a suggestion. When you have two totally separate classes with a bunch of the same public properties, you might want to create an intermediate class so you can pass them around without having to manually copy six property values each time. Then if you want to add one more property you don't have to modify a whole bunch of classes.

  • Related