Please, how would you get the average for quantity of the same date from the following data in kotlin.
A function to take this input and return an object with {"Monday" : 3.40, "Tuesday": 4.5}
and a brief explanation how to pass the data into the function (because it doesn't have specific task) will be much appreciated.
mapOf(
"orderId" to 554,
"creationDate" to "2017-03-25T10:35:20",
"orderLines" to arrayOf(
mapOf("productId" to 9872, "name" to "pencil", "quantity" to 3, "unitPrice" to 3.00)
)
),
mapOf(
"orderId" to 555,
"creationDate" to "2017-03-25T11:24:20",
"orderLines" to arrayOf(
mapOf("productId" to 9872, "name" to "Pencil", "quantity" to 1, "unitPrice" to 3.00),
mapOf("productId" to 1746, "name" to "Eraser", "quantity" to 1, "unitPrice" to 1.00)
)
),
mapOf(
"orderId" to 453,
"creationDate" to "2017-03-27T14:53:12",
"orderLines" to arrayOf(
mapOf("productId" to 5723, "name" to "Pen", "quantity" to 4, "unitPrice" to 4.22),
mapOf("productId" to 9872, "name" to "Pencil", "quantity" to 3, "unitPrice" to 3.12),
mapOf("productId" to 3433, "name" to "Erasers Set", "quantity" to 1, "unitPrice" to 6.15)
)
),
mapOf(
"orderId" to 690,
"creationDate" to "2017-03-26T11:14:00",
"orderLines" to arrayOf(
mapOf("productId" to 9872, "name" to "pencil", "quantity" to 4, "unitPrice" to 3.12),
mapOf("productId" to 4098, "name" to "Marker", "quantity" to 5, "unitPrice" to 4.50)
)
)```
CodePudding user response:
Using Map
s containing a bunch of unrelated types is a bad idea, you're not supposed to do that in a statically typed language like Kotlin (and you lose a lot of the advantages of static typing if you do). Having an unstructured pile of Any
s that you have to cast to the type you think it should be when you need to use it, that's asking for trouble.
You'd be better using classes instead, define your data:
data class OrderLine(
val productId: Int,
val name: String,
val quantity: Int,
val unitPrice: Float // *I don't recommend using floats for this*, see below
}
data class Order(
val orderId: Int,
val creationDate: String, // or you could parse it to a Date so you can work with it
val orderLines: List<OrderLine>
)
Now you can create your data using a data structure instead of a random collection of stuff that may or may not contain valid data (there are no guarantees with a Map<Any>
)
Order(
orderId = 554, // you don't need the parameter names, just using them for comparison
creationDate = "2017-03-25T11:24:20",
orderLines = listOf(
OrderLine(productId = 9872, name = "pencil", quantity = 3, unitPrice = 3.00f)
)
)
And then you can easily do work on your data. You could add a function on your Order
class that gives you the total item quantity for each order:
Order(...) {
fun getTotalQuantity() = orderLines.sumOf(OrderLine::quantity)
// or even better, as a property
val totalQuantity: Int get() = orderLines.sumOf { it.quantity } // same as above
}
// use that to sum all the order totals
val total = orders.sumOf { it.totalQuantity }
or you could just run a function over the whole set of data
val total = orders.sumOf { order ->
order.orderLines.sumOf { orderLine -> orderLine.quantity }
}
As for the price thing, you shouldn't use floats and doubles for monetary stuff - it's inaccurate and the errors can add up when you're working with a bunch of them. In your case, instead of having a unit price of 3.00
, I'd use an Int
and call it 300 (cents or whatever). That way it's always exactly the right number, and you can divide by 100 for display purposes