F# divide lists - list

i'm learning a new programming language, which is F# and I'm struggling to solve a method. I need to divide a list of movies and books into to 2 lists. One where the movies are and another one where the books are listed in. I can't use functions that already exists in F#. I link some exemples what i have done until now. Thank you in advance
type Movie =
{ movieName: string
duration: Nat
fileSize: Nat }
type Book =
{ bookName: string
pages: Nat }
type Activity =
| Watch of Movie
| Read of Book
let rec partitionActivities(activities: Activity list): (Book list * Movie list) =
match activities with
| [] -> [],[]
| x::_ -> match x with
| Read Book -> [Book],[]
| Watch Movie -> [],[Movie]
| _::xs -> partitionActivities(xs)
What my inputs are :
partitionActivities [
Read { bookName = "A"; pages = 45N }
Watch { movieName = "B"; duration = 120N; fileSize = 50N }
Read { bookName = "C"; pages = 700N }
Watch { movieName = "D"; duration = 100N; fileSize = 1024N }
Watch { movieName = "E"; duration = 150N; fileSize = 9001N }
Read { bookName = "F"; pages = 700N }
What result should be :
[
{ bookName = "A"; pages = 45N }
{ bookName = "C"; pages = 700N }
{ bookName = "F"; pages = 700N }
], [
{ movieName = "B"; duration = 120N; fileSize = 50N }
{ movieName = "D"; duration = 100N; fileSize = 1024N }
{ movieName = "E"; duration = 150N; fileSize = 9001N }
]

That is the right idea. Recurse with the tail of the list (xs), take the current Activity, determine if it involves a Movie or a Book, add it to the front of the corresponding list and return both lists:
let rec partitionActivities(activities: Activity list): (Book list * Movie list) =
match activities with
| [] -> [], []
| x::xs ->
let books, movies = partitionActivities(xs)
match x with
| Read book -> book::books, movies
| Watch movie -> books, movie::movies

Related

Putting children in one list

Please tell me how in such a data structure (simplified for better understanding) to bring all the children of the entity into one list:
fun main() {
val listOfEntities = listOf(
Entity(
name = "John",
entities = listOf(
Entity(
name = "Adam",
entities = listOf()
),
Entity(
name = "Ivan",
entities = listOf(
Entity(
name = "Henry",
entities = listOf(
Entity(
name = "Kate",
entities = listOf(
Entity(
name = "Bob",
entities = listOf()
)
)
)
)
)
)
)
)
)
)
val result = listOfEntities.flatMap { it.entities }.map { it.name }
println(result)
}
data class Entity(
val name: String,
val entities: List<Entity>
)
I expect to see following result:
[John, Adam, Ivan, Henry, Kate, Bob]
I try to use flatMap, but it did not lead to the expected result.
Thank you in advance!
You can traverse the tree of Entities recursively like this:
fun List<Entity>.flattenEntities(): List<Entity> =
this + flatMap { it.entities.flattenEntities() }
Then you can call
val result = listOfEntities.flattenEntities().map { it.name }
to obtain the desired result.
You could do it like this
fun List<Entity>.flatten(): List<String> {
return flatMap { listOf(it.name) + it.entities.flatten()}
}
and then
val result = listOfEntities.flatten()

Terraform aws_cloudfront_cache_policy pass multiple cookies to cookies_config

I can't seem to pass multiple cookies in the "items" list when in "cookies_config -> cookies"
Here is my variable:
variable "cache_policy_defaults" {
type = object({
name = string
comment = string
default_ttl = number
max_ttl = number
min_ttl = number
cookie_behavior = string
cookies_to_forward = optional(list(string))
header_behavior = string
headers_to_forward = optional(list(string))
query_string_behavior = string
query_strings_to_forward = optional(list(string))
}
)
default = {
name = ""
comment = ""
default_ttl = 60
max_ttl = 60
min_ttl = 60
cookie_behavior = "none"
cookies_to_forward = []
header_behavior = "none"
headers_to_forward = []
query_string_behavior = "none"
query_strings_to_forward = []
}
}
Here are my locals:
locals {
origin_id = "origin_${local.origin_config.domain_name}"
origin_config = merge(var.origin_defaults, var.origin_settings)
restrictions = merge(var.restrictions_defaults, var.restrictions_settings)
default_cache_behavior = merge(var.default_cache_behavior_defaults, var.default_cache_behavior_settings)
cache_policy = merge(var.cache_policy_defaults, var.cache_policy_settings)
cache_policy_name = "cache_policy_${var.name}"
}
Here is my tfvars:
"cache_policy_settings": {
"min_ttl": 30,
"max_ttl": 30,
"default_ttl": 30,
"cookie_behavior": "whitelist",
"cookies_to_forward": ["123", "456"]
}
Here is my main.tf:
resource "aws_cloudfront_cache_policy" "this" {
name = lookup(local.cache_policy, local.cache_policy.name, local.cache_policy_name)
comment = local.cache_policy.comment
default_ttl = local.cache_policy.default_ttl
max_ttl = local.cache_policy.max_ttl
min_ttl = local.cache_policy.min_ttl
parameters_in_cache_key_and_forwarded_to_origin {
cookies_config {
cookie_behavior = local.cache_policy.cookie_behavior
dynamic "cookies" {
for_each = local.cache_policy.cookies_to_forward != null ? local.cache_policy.cookies_to_forward : null
content {
items = local.cache_policy.cookies_to_forward
}
}
}
headers_config {
header_behavior = local.cache_policy.header_behavior
dynamic "headers" {
for_each = local.cache_policy.headers_to_forward != null ? local.cache_policy.headers_to_forward : null
content {
items = local.cache_policy.headers_to_forward
}
}
}
query_strings_config {
query_string_behavior = local.cache_policy.query_string_behavior
dynamic "query_strings" {
for_each = local.cache_policy.query_strings_to_forward != null ? local.cache_policy.query_strings_to_forward : null
content {
items = local.cache_policy.query_strings_to_forward
}
}
}
}
}
The docs state
items: (Required) A list of item names (cookies, headers, or query strings).
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_cache_policy#items
However, the list does not accept multiple items.
Error: Too many list items
on main.tf line 57, in resource "aws_cloudfront_cache_policy" "this":
57: cookies_config {
Attribute supports 1 item maximum, but config has 2 declared.
It seems that I should just be able to pass a list of items? If I change the my input list to only contain a single value, then it works.
Here is the trick:
for_each = local.cache_policy.cookies_to_forward != null ? [1] : null
This tells Terraform to create exactly one block by making the true value of the ternary [1].
Thanks Jason for putting me on the right track.

How to print the sum of types in a record in F#?

I have the below record for how many items were sold at a shop:
type ShopEarnings = { Item: string; Price: int; Quantity: int}
let pencils = { Item= "Pencils"; Price = 2; Quantity = 500 }
let pens = { Item= "Pens"; Price = 5; Quantity = 200 }
let labels = { Item= "Labels"; Price = 3; Quantity = 300 }
let rulers = { Item= "Rulers"; Price = 5; Quantity = 100 }
I want to calculate the total amount of items sold so I can print something like:
printfn "%i items were sold" totalItemsSold
and it will output
1100 items were sold
Also, I should not need to enter the items for addition manually in case there are 100 items.
I tried different approaches like List.sum but it would not work.
What would be the best way to calculate the total sum of "Quantity"?
List.sumBy will do it:
let totalItemsSold =
[pencils; pens; labels; rulers]
|> List.sumBy (fun earnings -> earnings.Quantity)
printfn "%i items were sold" totalItemsSold

Kotlin How to integrate/merge with same value in the List of data class

I want to merge same "startime" to one (step, distance and calorie) in the list, how can I to do this.
var listNewStepData = arrayListOf<NewStepData>()
data class
data class NewStepData (
val startTime: String?,
val endTime: String?,
val step: Int? = 0,
val distance: Int? = 0,
val calorie: Int? = 0
)
this is sample
NewStepData(startTime=2020-04-14T00:00:00.000Z, endTime=2020-04-14T00:00:00.000Z, step=4433, distance=0, calorie=0)
NewStepData(startTime=2020-04-14T00:00:00.000Z, endTime=2020-04-15T00:00:00.000Z, step=0, distance=0, calorie=1697)
NewStepData(startTime=2020-04-14T00:00:00.000Z, endTime=2020-04-14T00:00:00.000Z, step=0, distance=2436, calorie=0)
NewStepData(startTime=2020-04-15T00:00:00.000Z, endTime=2020-04-15T00:00:00.000Z, step=5423, distance=0, calorie=0)
NewStepData(startTime=2020-04-15T00:00:00.000Z, endTime=2020-04-16T00:00:00.000Z, step=0, distance=0, calorie=1715)
NewStepData(startTime=2020-04-15T00:00:00.000Z, endTime=2020-04-15T00:00:00.000Z, step=0, distance=3196, calorie=0)
I want to get this
NewStepData(startTime=2020-04-14T00:00:00.000Z, endTime=2020-04-15T00:00:00.000Z, step=4433, distance=2436, calorie=1697)
NewStepData(startTime=2020-04-15T00:00:00.000Z, endTime=2020-04-16T00:00:00.000Z, step=5423, distance=3196, calorie=1715)
thanks
You can use groupBy { } for your list. It will return a map of your grouping variable type to lists of your original type. And then, use flatMap to aggregate your data.
I assume that you take maximum end date which is maxBy and sum of distances, and steps which you need sumBy for, and calories which sumByDouble is the best choice.
Here's the sample code:
var grouped = listNewStepData.groupBy { it.startTime }.flatMap { entry -> NewStepData(startTime = entry.key,
endTime = entry.value.maxBy { item -> item.endTime },
step = entry.value.sumBy { item -> item.step },
distance = entry.value.sumBy { item -> item.distance },
calorie = entry.value.sumByDouble { item -> item.calorie })
}

how we find and replace array dictionary value in swift 3

My array has this dictionary I want to find and replace where dictionary h
attendance = "" and attendance = "A" and replace with attendance = "P"
I am using this:
checkedArray = [[String : AnyObject]]()
let index = find(checkedArray) { $0["attendance"] == "P" }
if let index = index {
checkedArray[index] = newDictionary
}
// Do any additional setup after loading the view.
}
func find<C: CollectionType>(collection: C, predicate: (C.Generator.Element) -> Bool) -> C.Index? {
for index in collection.startIndex ..< collection.endIndex {
if predicate(collection[index]) {
return index
}
}
return nil
}
[
{"studentID":"12","name":"panky","roll":"","attendance":"P"},
{"studentID":"14","name":"a","roll":"","attendance":""},
{"studentID":"4","name":"akshay","roll":"1","attendance":"E"},
{"studentID":"6","name":"anki","roll":"11","attendance":"P"},
{"studentID":"1","name":"mohit","roll":"2","attendance":"M"},
{"studentID":"5","name":"yogi","roll":"22","attendance":"L"},
{"studentID":"3","name":"Neha","roll":"3","attendance":"A"}
]
let dic: [[String : Any]] = [
["studentID":"12","name":"panky","roll":"","attendance":"P"],
["studentID":"14","name":"a","roll":"","attendance":""],
["studentID":"4","name":"akshay","roll":"1","attendance":"E"],
["studentID":"6","name":"anki","roll":"11","attendance":"P"],
["studentID":"1","name":"mohit","roll":"2","attendance":"M"],
["studentID":"5","name":"yogi","roll":"22","attendance":"L"],
["studentID":"3","name":"Neha","roll":"3","attendance":"A"]
]
let result : [Any] = dic.map { dictionary in
var dict = dictionary
if let attendance = dict["attendance"] as? String, attendance == "" || attendance == "A" {
dict["attendance"] = "P"
}
return dict
}