I have a json response like this:
{
"status": "success",
"count": 3,
"data": [
{
"_id": "604b266e7e2dd800159031e4",
"type": "expense",
"description": "This is an income",
"amount": 4555,
"createdAt": "2021-03-12T08:29:34.128Z",
"updatedAt": "2021-03-12T08:29:34.128Z",
"id": "604b266e7e2dd800159031e4"
},
{
"_id": "604b24ac7e2dd800159031e2",
"type": "expense",
"description": "This is an income",
"amount": 4555,
"createdAt": "2021-03-12T08:22:04.802Z",
"updatedAt": "2021-03-12T08:22:04.802Z",
"id": "604b24ac7e2dd800159031e2"
},
{
"_id": "604b24897e2dd800159031e1",
"type": "income",
"description": "This is an income",
"amount": 4555,
"createdAt": "2021-03-12T08:21:29.684Z",
"updatedAt": "2021-03-12T08:21:29.684Z",
"id": "604b24897e2dd800159031e1"
}
]
}
There is a "type" key in the object array whose value can either be "expense" or "income".
Now, in my android, how do I get only data for "expense" and "income" NOT all of them.
Example I want to run this request but get only the type whose value is "expense". How do I do it with Kotlin?
I am using Retrofit
Resource.Status.SUCCESS -> {
if (it.data?.status == "success") {
for (expenditureType in it.data.data){
val type = expenditureType.type
//logic here
}
}
}
val expenseList = it.data.data.filter { it.type = "expense" }
It is as simple as that.
If you want list of all types,
you can get list of string using map function.
val list:List<String> = it.data.data.map {
it.type
}
If you want a filtered list with specific types,
val list = it.data.data.filter {
it.type == "expense" or it.type == "income"
}
Related
I have a list of items, these items can have children, and the children can also have children. The API I'm using returns a list of these items in a single Array of Objects and provides a path property to consume the list and organise it how you choose. Each child adds an extra incrementing -000n to the path starting at 0001. I can't work out how to consume the path value to organise the list of Objects into nested Arrays where each item has it's own respective children[] Array.
I'm using Typescript/JS and Kotlin (Android Framework).
Been trying to figure this out for a while, I'd appreciate some community input on the problem. Hope I've explained it well enough, thanks!
Example:
|--group (0001)
|--item (0001-0001)
|--item (0001-0001-0001)
|--item (0001-0001-0001-0001)
|--item (0001-0001-0001-0002)
|--item (0001-0002)
|--item (0001-0002-0001)
|--item (0001-0002-0001-0001)
|--item (0001-0002-0001-0001-0001)
|--item (0001-0002-0001-0002)
|--item (0001-0003)
|--group (0002)
|--item (0002-0001)
Payload:
{
"items": [
{
"name": "cameras",
"type": "group",
"path": "0001"
},
{
"name": "camera-1",
"type": "equipment",
"path": "0001-0001"
},
{
"name": "charger",
"type": "power",
"path": "0001-0001-0001"
},
{
"name:": "cable",
"type": "power",
"path": "0001-0001-0001-0001"
},
{
"name": "adapter",
"type": "power",
"path": "0001-0001-0001-0002"
},
{
"name": "camera-2",
"type": "equipment",
"path": "0001-0002"
},
// etc
{
"name": "lights",
"type": "group",
"path": "0002"
}
// etc
]
}
Preferred outcome:
{
"items": [
{
"name": "cameras",
"type": "group",
"path": "0001",
"children": [
{
"name": "camera-1",
"type": "equipment",
"path": "0001-0001",
"children": [
{
"name": "charger",
"type": "power",
"path": "0001-0001-0001",
"children": [
{
"name:": "cable",
"type": "power",
"path": "0001-0001-0001-0001"
},
{
"name": "adapter",
"type": "power",
"path": "0001-0001-0001-0002"
}
]
}
]
},
{
"name": "camera-2",
"type": "equipment",
"path": "0001-0002",
// children as above
}
]
},
{
"name": "lights",
"type": "group",
"path": "0002",
// children as above
}
]
}
You could use a map to store the items by their path while you build the item tree. Here's an example:
data class Item(
val name: String,
val type: String,
val path: String,
val children: MutableList<Item> = mutableListOf(),
)
val itemsList = <flat list of items, parsed from json>
val pathMap = mutableMapOf<String, Item>()
val itemsTree = mutableListOf<Item>()
for (item in itemsList) {
pathMap[item.path] = item
if ('-' in item.path) {
val parentPath = item.path.substringBeforeLast('-')
val parent = pathMap[parentPath]
if (parent != null) {
parent.children += item
}
} else {
itemsTree += item
}
}
Here itemsList is the original list of items, in a flat hierarchy, and itemsTree is a list of top-level items only, each with a children attribute containing children items. This does require however that all "parents" appear before any of their children in itemsList, but could be easily modified to account for that not being the case.
I'm not sure if you wanted Kotlin or TypeScript, but the concept is easily interchangeable between the two, all you need is a map-like data structure.
I have a complex JSON which I need to parse and store the information that are inside the JSON data into Room database. Is it possible to store the whole JSON in Room? If that is possible I am up for that too. I am using Kotlin. Can anyone guide me to it?
Here's my JSON sample:
{
"chapters": [
{
"play": "manual",
"items": [
{
"image": "/path/to/image",
"background": "#ffffff",
"text": "text to show on image",
"points": 1,
"voice": {
"type": "tts"
},
"words": {
"type": "wav",
"file": "/path to words file",
"parts": [
{
"word": "text",
"from": 122,
"to": 116
}
]
}
},
{
"image": "/path/to/image",
"background": "#ffffff",
"text": "text to show on image",
"points": 1,
"voice": {
"type": "wav",
"file": "/path/to/file"
}
}
]
}
]
}
I want to sort my main array using a child array value. Output as below:
{
"status": true,
"statusCode": 100,
"message": "",
"data": {
"win": [
{
"id": "1",
"admin": [
{
"id": "38",
"name": "Admin 05",
"point": {
"id": "96",
"name": "96"
}
}
]
},
{
"id": "2",
"admin": [
{
"id": "39",
"name": "Admin 06",
"point": {
"id": "95",
"name": "95"
}
}
]
},
{
"id": "3",
"admin": [
{
"id": "26",
"name": "Admin 05",
"point": {
"id": "98",
"name": "98"
}
}
]
}
]
}
}
I want array as below but I am not able to do so.
id = 3 // first
id = 1 // second
id = 2 // third and so on.
I tried below:
Collections.sort(loWinArray, object : Comparator<Win> {
override fun compare(obj1: Win, obj2: Win): Int {
// ## Ascending order
return (obj2.admin.get(0).point!!.name.toInt() - obj1.admin.get(0).point!!.name.toInt()) // To compare string values
}
})
Can any one please help?
If you want it to be sorted by the point ID, largest first to smallest last, try this:
val sortedArray = loWinArray.sortedByDescending { item -> item.admin.first().id.toInt() }
Try this for ascending order what you have tried it will return descending order
Collections.sort(loWinArray, object : Comparator<Win> {
override fun compare(obj1: Win, obj2: Win): Int {
// ## Ascending order
return obj1.admin.get(0).point!!.name.toInt() - obj2.admin.get(0).point!!.name.toInt()
}
})
I'm having this response JSON that theorically follows the JSON API specs. I'm trying to parse with the moshi-jsonapi library but I don't know how to parse the some_objects relationship. In the SomeType class I have a member HasMany<SomeObject> someObjects and the class SomeObject is annotated in a proper way:
#JsonApi(type = "some_objects")
public class SomeObject extends Resource {
//....
}
But, after doing the parsing, I'm getting the someObjects member as null. Anyone knows why?
The JSON is that one:
"links": {
"self": "someurl/params"
},
"data": [
{
"type": "some_type",
"id": "12345",
"attributes": {
"attr1": 1,
"attr2": 2,
"attr3": 3
},
"relationships": {
"some_objects": {
"data": [
{
"type": "some_objects",
"id": "1"
},
{
"type": "some_objects",
"id": "2"
}
]
}
}
}
],
"included": [
{
"type": "some_objects",
"id": "1",
"attributes": {
"id": "1",
"parentId": "1"
},
"relationships": {
"subobjects": {
"data": [
{
"type": "subobjects",
"id": "2"
}
]
}
}
{
"type": "subobjects",
"id": "2",
"attributes": {
"metadata": {
"code": "AA"
},
"id": "2",
"parentId": "1"
}
}
],
"meta": {
"total": 1,
"totalCount": 1,
"correction": []
}
}
The only problem was the name of the member, after changing someObjects by 'some_objects' it worked like a charm.
I am getting the response
{
"returnCode": "0",
"message": "Sucessfully get credit card for value(1) ",
"token": "",
"CreditCard": {
"class": "CreditCard",
"id": 1,
"bankName": "NA",
"cardNumber": "1233435467789",
"ccvNumber": "3455",
"dateCreated": "2012-02-10T10:20:06Z",
"expiryDate": "2012-02-29T18:30:00Z",
"expiryDateStr": null,
"lastUpdated": "2012-02-10T10:20:06Z",
"securityCode": null,
"type": {
"enumType": "CreditCardType",
"name": "Visa"
},
"user": {
"class": "User",
"id": 4
}
}
}
I can't change server code, so how do i parse it. any helped..
your enum:
enum CreditCardType{
Visa, MasterCard, Diners
}
and while parsing, when you reach till type
//param is JSONObject
CreditCardType card = CreditCardType.valueOf(param.getString("name"));