I have current date and I have of list which is coming from server. I want to find all first nearest data.
"Results": [
{
"date": "May 9, 2020 8:09:03 PM",
"id": 1
},
{
"date": "Apr 14, 2020 8:09:03 PM",
"id": 2
},
{
"date": "Mar 15, 2020 8:09:03 PM",
"id": 3
},
{
"date": "May 9, 2020 8:19:03 PM",
"id": 4
}
],
Today date is Wed Jul 20 00:00:00 GMT+01:00 2022 I am getting through this my own StackOverflow. Inside this SO I am taking current date.
Expected Output
[Result(date=May 9, 2020 8:09:03 PM, id = 1), Result(date=May 9, 2020 8:19:03 PM, id = 4)]
So How can I do in idiomatic way in kotlin ?
There are quite a few ways this question could be solved with, ranging from simple to moderately complex depending on requirements such as efficiency. With some assumptions, below is a linear-time solution that is decently idiomatic and is only 3 lines in essence.
import kotlin.math.abs
import java.lang.Long.MAX_VALUE
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
import java.time.temporal.Temporal
data class Result(val date: LocalDateTime, val id: Int)
fun getClosestDays(toDate: Temporal, results: List<Result>): List<Result> {
// Find the minimum amount of days to the current date
var minimumDayCount = MAX_VALUE
results.forEach { minimumDayCount = minOf(minimumDayCount, abs(ChronoUnit.DAYS.between(toDate, it.date))) }
// Grab all results that match the minimum day count
return results.filter { abs(ChronoUnit.DAYS.between(toDate, it.date)) == minimumDayCount }
}
fun main() {
getClosestDays(
LocalDateTime.now(),
listOf(
Result(LocalDateTime.of(2020, 5, 9, 8, 9, 3), 1),
Result(LocalDateTime.of(2020, 4, 14, 8, 9, 3), 2),
Result(LocalDateTime.of(2020, 3, 15, 8, 9, 3), 3),
Result(LocalDateTime.of(2020, 5, 9, 8, 19, 3), 4)
)
).also { println(it) }
}
Here is the output:
[Result(date=2020-05-09T08:09:03, id=1), Result(date=2020-05-09T08:19:03, id=4)]
And here you can play with it yourself.
Related
I have a table as below:
id
mid
handphone
coupono
status
1
1
0811111111
1
1
2
1
08222222222
2
1
3
1
08222222222
3
1
4
1
08222222222
4
1
5
1
08111111111
5
1
6
2
08333333333
6
1
7
2
08333333333
7
1
8
2
08444444444
8
1
-----
-----
---------------
--------
-------
I want to query the table using WHERE clause on mId column and filtered the couponno or listed on handphone number. How to query that?
The result that I want is:
{
"08111111111": [{
"Id": 1,
"CouponNo": 1,
"Status": 1
}, {
"Id": 5,
"CouponNo": 5,
"Status": 1
}],
"08222222222": [{
"Id": 2,
"CouponNo": 2,
"Status": 1
}, {
"Id": 3,
"CouponNo": 3,
"Status": 1
}, {
"Id": 4,
"CouponNo": 4,
"Status": 1
}]
}
Requiring Handphone to be object keys in your JSON makes it difficult to produce from SQL and probably won't scale well on the receiving side either as you add more data over time.
Here is some pivot-based SQL that will produce your desired JSON...
create table dbo.PivotJsonStuff (
Id int,
[Mid] int,
Handphone varchar(11),
CouponNo int,
Status int
);
insert dbo.PivotJsonStuff (Id, [Mid], Handphone, CouponNo, Status)
values
(1, 1, '08111111111', 1, 1),
(2, 1, '08222222222', 2, 1),
(3, 1, '08222222222', 3, 1),
(4, 1, '08222222222', 4, 1),
(5, 1, '08111111111', 5, 1),
(6, 2, '08333333333', 6, 1),
(7, 2, '08333333333', 7, 1),
(8, 2, '08444444444', 8, 1);
select
[08111111111] = json_query([08111111111]),
[08222222222] = json_query([08222222222])
from (
select Handphone,
[JSON] = (
select PJS2.Id, PJS2.CouponNo, PJS2.Status
from dbo.PivotJsonStuff PJS2
where PJS2.Handphone = PJS1.Handphone
for json path
)
from dbo.PivotJsonStuff PJS1
group by Handphone
) src
pivot (max([JSON]) for Handphone in ([08111111111], [08222222222])) pvt
for json path, without_array_wrapper;
{
"08111111111": [
{
"Id": 1,
"CouponNo": 1,
"Status": 1
},
{
"Id": 5,
"CouponNo": 5,
"Status": 1
}
],
"08222222222": [
{
"Id": 2,
"CouponNo": 2,
"Status": 1
},
{
"Id": 3,
"CouponNo": 3,
"Status": 1
},
{
"Id": 4,
"CouponNo": 4,
"Status": 1
}
]
}
I use the Google AdWords API to collect information about the search volume for a specific keyword. But the data I get as a response doesn't match with the data from the keyword planner or other keyword tools. Here I check the search volume for the keyword "Hunde" in Berlin, Germany in german.
targeting_service = adwordsClient.GetService('TargetingIdeaService')
selector = {'ideaType': 'KEYWORD', 'requestType' : 'STATS'}
selector['requestedAttributeTypes'] = ['KEYWORD_TEXT', 'SEARCH_VOLUME', 'TARGETED_MONTHLY_SEARCHES']
offset = 0
selector['paging'] = {'startIndex' : str(offset), 'numberResults' : str(1)}
selector['searchParameters'] = [{
'xsi_type': 'RelatedToQuerySearchParameter',
'queries': ["hunde"]
}]
selector['searchParameters'].append({
'xsi_type': 'LocationSearchParameter',
'locations': [{'id': '1003854'}]
})
selector['searchParameters'].append({
'xsi_type': 'LanguageSearchParameter',
'languages': [{'id': '1001'}]
})
page = targeting_service.get(selector)
print(page)
As a response I get:
{
'totalNumEntries': 1,
'entries': [
{
'data': [
{
'key': 'KEYWORD_TEXT',
'value': {
'Attribute.Type': 'StringAttribute',
'value': 'hunde'
}
},
{
'key': 'TARGETED_MONTHLY_SEARCHES',
'value': {
'Attribute.Type': 'MonthlySearchVolumeAttribute',
'value': [
{
'year': 2020,
'month': 12,
'count': 4743382
},
{
'year': 2020,
'month': 11,
'count': 455583
},
{
'year': 2020,
'month': 10,
'count': 8797951
},
{
'year': 2020,
'month': 9,
'count': 5218694
},
{
'year': 2020,
'month': 8,
'count': 5089585
},
{
'year': 2020,
'month': 7,
'count': 3149591
},
{
'year': 2020,
'month': 6,
'count': 3020638
},
{
'year': 2020,
'month': 5,
'count': 4928527
},
{
'year': 2020,
'month': 4,
'count': 754959
},
{
'year': 2020,
'month': 3,
'count': 5649676
},
{
'year': 2020,
'month': 2,
'count': 1590789
},
{
'year': 2020,
'month': 1,
'count': 2506674
}
]
}
},
{
'key': 'SEARCH_VOLUME',
'value': {
'Attribute.Type': 'LongAttribute',
'value': 3825504
}
}
]
}
]
}
But this data doesn't match with the data from the keyword planer.
Avg. monthly searches (Keyword planner): 10K – 100K
Does somebody knows why the data I'm receiving is wrong?
These questions pop up somewhat frequently and are generally not easy to answer. Did you make sure that the specified searchParameters in your request correspond exactly to what you are using in the Keyword Planner?
Additionally, you could check out the KeywordPlanService of the newer Ads API. According to this post by a Google Ads API advisor, it should be closer to what you can do in the web UI than the Adwords API's TargetingIdeaService.
If OP didn't figure it out, i've had the same headaches.
I solved this when adding NetworkSearchParameter to [searchparameter] so the API only returns google data.
my code after adding in the additional argument.
selector['searchParameters'] = [{
'xsi_type' : 'RelatedToQuerySearchParameter',
'queries' : sublist,
},
{
'xsi_type':'LocationSearchParameter',
'locations' : [country_ids[country]],
},
{
'xsi_type': 'NetworkSearchParameter',
'networkSetting': {
'targetGoogleSearch': True,
'targetSearchNetwork': False,
'targetContentNetwork': False,
'targetPartnerSearchNetwork': False
}}]
I've data for ReactNativeWheelPicker which looks like this:
const hoursData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
and than picker receives these data: data={hoursData}
I tried to use following method to convert e.g. 1 to 01:
(hoursData < 10 ? "0" + hoursData : hoursData)
Unfortunately, wherever I put this, wheel picker always shows single number.
I'm using wheel picker from this repo: https://github.com/ElekenAgency/ReactNativeWheelPicker
Any suggestions would be appreciated ;)
EDIT (updated full code):
const hoursData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
class TimePickerMenu extends Component {
constructor(props) {
super(props);
this.state = {
selectedHours: 9,
};
}
}
render() {
return (
<View style={styles.rowPicker}>
<WheelPicker
onItemSelected={ (event)=> this.setState({ index: event.position, selectedHours: event.data }) }
isCurved
isCyclic
data={hoursData}
style={styles.wheelPicker}
/>
</View>
);
}
}
You need to do this
const hoursData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
const data = hoursData.map(data => {
if (data < 10) {
return '0' + data
}
return '' + data
})
Similar questions asked here before:
Count items for a single key: jq count the number of items in json by a specific key
Calculate the sum of object values:
How do I sum the values in an array of maps in jq?
Question
How to emulate the COUNT aggregate function which should behave similarly to its SQL original? Let's extend this question even more to include other regular SQL functions:
COUNT
SUM / MAX/ MIN / AVG
ARRAY_AGG
The last one is not a standard SQL function - it's from PostgreSQL but is quite useful.
At input comes a stream of valid JSON objects. For demonstration let's pick a simple story of owners and their pets.
Model and data
Base relation: Owner
id name age
1 Adams 25
2 Baker 55
3 Clark 40
4 Davis 31
Base relation: Pet
id name litter owner_id
10 Bella 4 1
20 Lucy 2 1
30 Daisy 3 2
40 Molly 4 3
50 Lola 2 4
60 Sadie 4 4
70 Luna 3 4
Source
From above we get a derivative relation Owner_Pet (a result of SQL JOIN of the above relations) presented in JSON format for our jq queries (the source data):
{ "owner_id": 1, "owner": "Adams", "age": 25, "pet_id": 10, "pet": "Bella", "litter": 4 }
{ "owner_id": 1, "owner": "Adams", "age": 25, "pet_id": 20, "pet": "Lucy", "litter": 2 }
{ "owner_id": 2, "owner": "Baker", "age": 55, "pet_id": 30, "pet": "Daisy", "litter": 3 }
{ "owner_id": 3, "owner": "Clark", "age": 40, "pet_id": 40, "pet": "Molly", "litter": 4 }
{ "owner_id": 4, "owner": "Davis", "age": 31, "pet_id": 50, "pet": "Lola", "litter": 2 }
{ "owner_id": 4, "owner": "Davis", "age": 31, "pet_id": 60, "pet": "Sadie", "litter": 4 }
{ "owner_id": 4, "owner": "Davis", "age": 31, "pet_id": 70, "pet": "Luna", "litter": 3 }
Requests
Here are sample requests and their expected output:
COUNT the number of pets per owner:
{ "owner_id": 1, "owner": "Adams", "age": 25, "pets_count": 2 }
{ "owner_id": 2, "owner": "Baker", "age": 55, "pets_count": 1 }
{ "owner_id": 3, "owner": "Clark", "age": 40, "pets_count": 1 }
{ "owner_id": 4, "owner": "Davis", "age": 31, "pets_count": 3 }
SUM up the number of whelps per owner and get their MAX (MIN/AVG):
{ "owner_id": 1, "owner": "Adams", "age": 25, "litter_total": 6, "litter_max": 4 }
{ "owner_id": 2, "owner": "Baker", "age": 55, "litter_total": 3, "litter_max": 3 }
{ "owner_id": 3, "owner": "Clark", "age": 40, "litter_total": 4, "litter_max": 4 }
{ "owner_id": 4, "owner": "Davis", "age": 31, "litter_total": 9, "litter_max": 4 }
ARRAY_AGG pets per owner:
{ "owner_id": 1, "owner": "Adams", "age": 25, "pets": [ "Bella", "Lucy" ] }
{ "owner_id": 2, "owner": "Baker", "age": 55, "pets": [ "Daisy" ] }
{ "owner_id": 3, "owner": "Clark", "age": 40, "pets": [ "Molly" ] }
{ "owner_id": 4, "owner": "Davis", "age": 31, "pets": [ "Lola", "Sadie", "Luna" ] }
Here's an alternative, not using any custom functions with basic JQ. (I took the liberty to get rid of redundant parts of the question)
Count
In> jq -s 'group_by(.owner_id) | map({ owner_id: .[0].owner_id, count: map(.pet) | length})'
Out>[{"owner_id": "1","pets_count": 2}, ...]
Sum
In> jq -s 'group_by(.owner_id) | map({owner_id: .[0].owner_id, sum: map(.litter) | add})'
Out> [{"owner_id": "1","sum": 6}, ...]
Max
In> jq -s 'group_by(.owner_id) | map({owner_id: .[0].owner_id, max: map(.litter) | max})'
Out> [{"owner_id": "1","max": 4}, ...]
Aggregate
In> jq -s 'group_by(.owner_id) | map({owner_id: .[0].owner_id, agg: map(.pet) })'
Out> [{"owner_id": "1","agg": ["Bella","Lucy"]}, ...]
Sure, these might not be the most efficient implementations, but they show nicely how to implement custom functions oneself. All that changes between the different functions is inside the last map and the function after the pipe | (length, add, max)
The first map iterates over the different groups, taking the name from the first item, and using map again to iterate over the same-group items. Not as pretty as SQL, but not terribly more complicated.
I learned JQ today, and managed to do this already, so this should be encouraging for anyone getting started. JQ is neither like sed nor like SQL, but not terribly hard either.
Extended jq solution:
Custom count() function:
jq -sc 'def count($k): group_by(.[$k])[] | length as $l | .[0]
| .pets_count = $l
| del(.pet_id, .pet, .litter);
count("owner_id")' source.data
The output:
{"owner_id":1,"owner":"Adams","age":25,"pets_count":2}
{"owner_id":2,"owner":"Baker","age":55,"pets_count":1}
{"owner_id":3,"owner":"Clark","age":40,"pets_count":1}
{"owner_id":4,"owner":"Davis","age":31,"pets_count":3}
Custom sum() function:
jq -sc 'def sum($k): group_by(.[$k])[] | map(.litter) as $litters | .[0]
| . + {litter_total: $litters | add, litter_max: $litters | max}
| del(.pet_id, .pet, .litter);
sum("owner_id")' source.data
The output:
{"owner_id":1,"owner":"Adams","age":25,"litter_total":6,"litter_max":4}
{"owner_id":2,"owner":"Baker","age":55,"litter_total":3,"litter_max":3}
{"owner_id":3,"owner":"Clark","age":40,"litter_total":4,"litter_max":4}
{"owner_id":4,"owner":"Davis","age":31,"litter_total":9,"litter_max":4}
Custom array_agg() function:
jq -sc 'def array_agg($k): group_by(.[$k])[] | map(.pet) as $pets | .[0]
| .pets = $pets | del(.pet_id, .pet, .litter);
array_agg("owner_id")' source.data
The output:
{"owner_id":1,"owner":"Adams","age":25,"pets":["Bella","Lucy"]}
{"owner_id":2,"owner":"Baker","age":55,"pets":["Daisy"]}
{"owner_id":3,"owner":"Clark","age":40,"pets":["Molly"]}
{"owner_id":4,"owner":"Davis","age":31,"pets":["Lola","Sadie","Luna"]}
This is a nice exercise, but SO is not a programming service, so I will focus here on some key concepts for generic solutions in jq that are efficient, even for very large collections.
GROUPS_BY
The key to efficiency here is avoiding the built-in group_by, as it requires sorting. Since jq is fundamentally stream-oriented, the following definition of GROUPS_BY is likewise stream-oriented. It takes advantage of the efficiency of key-based lookups, while avoiding calling tojson on strings:
# emit a stream of the groups defined by f
def GROUPS_BY(stream; f):
reduce stream as $x ({};
($x|f) as $s
| ($s|type) as $t
| (if $t == "string" then $s else ($s|tojson) end) as $y
| .[$t][$y] += [$x] )
| .[][] ;
distinct and count_distinct
# Emit an array of the distinct entities in `stream`, without sorting
def distinct(stream):
reduce stream as $x ({};
($x|type) as $t
| (if $t == "string" then $x else ($x|tojson) end) as $y
| if (.[$t] | has($y)) then . else .[$t][$y] += [$x] end )
| [.[][]] | add ;
# Emit the number of distinct items in the given stream
def count_distinct(stream):
def sum(s): reduce s as $x (0;.+$x);
reduce stream as $x ({};
($x|type) as $t
| (if $t == "string" then $x else ($x|tojson) end) as $y
| .[$t][$y] = 1 )
| sum( .[][] ) ;
Convenience function
def owner: {owner_id,owner,age};
Example: "COUNT the number of pets per owner"
GROUPS_BY(inputs; .owner_id)
| (.[0] | owner) + {pets_count: count_distinct(.[]|.pet_id)}
Invocation: jq -nc -f program1.jq input.json
Output:
{"owner_id":1,"owner":"Adams","age":25,"pets_count":2}
{"owner_id":2,"owner":"Baker","age":55,"pets_count":1}
{"owner_id":3,"owner":"Clark","age":40,"pets_count":1}
{"owner_id":4,"owner":"Davis","age":31,"pets_count":3}
Example: "SUM up the number of whelps per owner and get their MAX"
GROUPS_BY(inputs; .owner_id)
| (.[0] | owner)
+ {litter_total: (map(.litter) | add)}
+ {litter_max: (map(.litter) | max)}
Invocation: jq -nc -f program2.jq input.json
Output: as given.
Example: "ARRAY_AGG pets per owner"
GROUPS_BY(inputs; .owner_id)
| (.[0] | owner) + {pets: distinct(.[]|.pet)}
Invocation: jq -nc -f program3.jq input.json
Output:
{"owner_id":1,"owner":"Adams","age":25,"pets":["Bella","Lucy"]}
{"owner_id":2,"owner":"Baker","age":55,"pets":["Daisy"]}
{"owner_id":3,"owner":"Clark","age":40,"pets":["Molly"]}
{"owner_id":4,"owner":"Davis","age":31,"pets":["Lola","Sadie","Luna"]}
I started learning C some weeks ago and today I started learning Swift. The code is the following:
import Foundation
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 8, 16, 25],
]
var largest = 0;
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number;
}
}
}
println(largest);
Why do I need kind in the for-in thingy? For "Prime", "Square", ..., right? Can I work with that somehow, too?
“Add another variable to keep track of which kind of number was the largest, as well as what that largest number was.”
How do I build that in?
import Foundation
var largest = 0;
var largestKind: String?;
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 8, 16, 25],
]
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number;
largestKind = kind;
}
}
}
println("The number \(largest) is from the type \(largestKind)");
That's my solution at the moment. However, the output is
The number 25 is from the type Optional("Square")
How do I get rid of the 'Optional("")? I just want the word Square. I tried removing the question mark (var largestKind: String?; to var largestKind: String;) but I get an error doing that.
For those who have the same question, this is another solution I've found. var largestKind is still optional because of String? but the exclamation mark at the end \(largestKind!) makes it possible to access the value without having that optional stuff around the actual content.
import Foundation
var largest = 0;
var largestKind: String?;
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 8, 16, 25],
]
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number;
largestKind = kind;
}
}
}
println("The number \(largest) is from the type \(largestKind!).");