List of Records in F#? - list

How do you work with a List of Records in F#? How would you even pass that as an argument in a function? I want to do something like this:
type Car = {
Color : string;
Make : string;
}
let getRedCars cars =
List.filter (fun x -> x.Color = "red") cars;
let car1 = { Color = "red"; Make = "Toyota"; }
let car2 = { Color = "black"; Make = "Ford"; }
let cars = [ car1; car2; ]
I need a way to tell my function that "cars" is a List of Car records.

Your code works just fine. It can also be written:
let getRedCars cars =
List.filter (function {Color = "red"} -> true | _ -> false) cars
If you're ever concerned the wrong signature is being inferred, you can add type annotations. For example:
let getRedCars (cars:Car list) : Car list = //...

Related

How to modify an item in a list?

I'm a bit confused how to modify an item in a list. This is my structure:
type alias Player =
{ id : Int
, name : String
, isActive : Bool
}
type alias Model =
{ players : List Player
, newPlayer : Player
}
So I have a list of Players, and I want to edit a specific Player in the list (for example changing Player with Id = 2 field "isActive" to True). How could I go about this?
As a helper, you can consider using List.Extra.updateIf
newPlayers = players
|> List.Extra.updateIf (\player -> player.id == 2) (\player -> { player | isActive = True })
One solution is to use List.map:
setIsActiveForPlayer : List Player -> Int -> Bool -> List Player
setIsActiveForPlayer players id isActive =
let
update player =
if player.id == id then
{ player | isActive = isActive }
else
player
in
players |> List.map update
Another solution performs the iteration “by hand”:
setIsActiveForPlayer : List Player -> Int -> Bool -> List Player
setIsActiveForPlayer players id isActive =
case players of
[] ->
[]
player :: rest ->
if player.id == id then
{ player | isActive = isActive } :: rest
else
player :: setActivePlayer rest id isActive
This should be slightly more efficient because it reuses the tail of the list following the updated player.

Clickable activities list Kotlin

I'm retrieving data to list and I need to make 2 different intents. "Activities" needs to start "e" intent and rest starts "i" intent.
class MyAdapter(private val context : Activity, private val arrayList : ArrayList<Person>) : ArrayAdapter<Person>(context,
R.layout.list_item, arrayList) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val inflater : LayoutInflater = LayoutInflater.from(context)
val view : View = inflater.inflate(R.layout.list_item, null)
val imageView : ImageView = view.findViewById(R.id.profile_pic)
val activities : TextView = view.findViewById(R.id.activity_name)
val person_name : TextView = view.findViewById(R.id.name_list)
val activity_time : TextView = view.findViewById(R.id.time)
val checkbox : ImageView = view.findViewById(R.id.checkbox)
val person_icon : ImageView = view.findViewById(R.id.person_icon)
imageView.setImageResource(arrayList[position].imageID)
activities.text = arrayList[position].activities
person_name.text = arrayList[position].name
activity_time.text = arrayList[position].activityTime
checkbox.setImageResource(arrayList[position].checkbox)
person_icon.setImageResource(arrayList[position].person_icon)
return view
}
}
binding.listview.adapter = MyAdapter(this, personArrayList)
binding.listview.isClickable = true
binding.listview.setOnItemClickListener { parent, view, position, id ->
val name = name[position]
val activities = activities[position]
val activityTime = activityTime[position]
val description = description[position]
val imageID = imageID[position]
val i = Intent(this, DescriptionActivity::class.java)
val e = Intent(this, ProfileScreen::class.java)
i.putExtra("name", name)
i.putExtra("activityTime", activityTime)
e.putExtra("activities", activities)
i.putExtra("imageID", imageID)`your text`
i.putExtra("description", description)
startActivity(i)
}
startActivity (e) overrides startActivity(i)
and making activities OnClickListener crashes the app.

How to maintain sub-type of an object in a Chapel array

Following up on an earlier SO question, now I want to collect the Fruit into a basket but know the sub-type on the way out.
class Banana : Fruit {
var color: string;
}
class Apple: Fruit {
var poison: bool;
}
class Fruit {
}
var a = new Apple(poison=true);
var b = new Banana(color="green");
if (a.type == Apple) {
writeln("Go away doctor!");
}
var basketDom = {1..1};
var basket: [basketDom] Fruit;
basket.push_back(a);
basket.push_back(b);
for b in basket {
writeln(b.type:string);
}
This prints the supertype Fruit. How can I get Apples and Bananas out of this basket?
A quick hack (unless an actual solution to this exists) would be send a tuple into the basket where the tuple would represent (type_of_object, typecasted_object).
Your code would hence become,
var basketDom = {1..1};
var basket: [basketDom] (string, Fruit);
basket.push_back((a.type:string, a));
basket.push_back((b.type:string, b));
for b in basket {
writeln(b);
}
This will give you
(Apple, {poison = true})
(Banana, {color = green})
Further, you can access the types using the index. eg - b[1] would be the type and b[2] the object content.
To access the class variables such as poison and color after this, you could do something like
if (b[1] == "Banana") {
var obj = b[2]: Banana;
writeln(obj.color);
}
and similarily for the class Apple.

ember-leaflet drag point to latlng

on my polygon 'dragend' function i get the new position via (e.target._newPos) that represents the position on my layer.
But when i convert that point as follows:
let containerPoint = layer._map.layerPointToContainerPoint(e.target._newPos);
let latlng = layer._map.containerPointToLatLng(containerPoint);
i get some coordinates that's what i want. But when i try to present them on my leaflet map layer an zoomin or out that point jumps on my map so wtf is going on?
import PolygonLayer from 'ember-leaflet/components/polygon-layer';
.
.
.
draggable.on('dragend', (e) => {
let containerPoint = layer._map.layerPointToContainerPoint(e.target._newPos);
let latlng = layer._map.containerPointToLatLng(containerPoint);
let dragEnd = this.get('onDragEnd');
dragEnd(latlng);
});
In my template i have a presentation of a map
items: {},
i have a item component
didRender() {
let layer = this.get('_layer');
let path = layer && layer._path;
if (!path) {
return;
}
let draggable = new L.Draggable(path);
draggable.enable();
draggable.on('dragend', (e) => {
let containerPoint = layer._map.layerPointToContainerPoint(e.target._newPos);
let latlng = layer._map.containerPointToLatLng(containerPoint);
let dragEnd = this.get('onDragEnd');
dragEnd(latlng);
});
},
so onDragEnd i will update the dragged items position with new latlngs but after my update the item is jumping on map

swift 3, PHFetchResult.enumerateObjects error

In swift 3,the method is show me "ambiguous use of 'enumerateObjects'",what happen.how can i do?
extension PHFetchResult {
public func assetCollection() -> [PHAssetCollection] {
var list :[PHAssetCollection] = []
self.enumerateObjects { (object, index, stop) in
if object is PHAssetCollection {
let collection = object as! PHAssetCollection
list.append(collection)
}
}
return list
}
}
Swift 3.0: Just add the Round Brackets before Curly Brackets starts after enumerateObjects.
extension PHFetchResult {
public func assetCollection() -> [PHAssetCollection] {
var list :[PHAssetCollection] = []
self.enumerateObjects ({ (object, index, stop) in
if object is PHAssetCollection {
let collection = object as! PHAssetCollection
list.append(collection)
}
})
return list
}
}
Do something like this noh. You can't directly add extension for PHFetchResult because it has other ObjectType as its generic parameter PHFetchResult<ObjectType> . So you must do something else.
class FetchPhoto {
class func assetCollection() -> [PHAssetCollection] {
var list :[PHAssetCollection] = []
PHAssetCollection.fetchMoments(with: nil).enumerateObjects(EnumerationOptions.concurrent) { (collection, _, _) in
list.append(collection)
}
return list
}
}
PHAssetCollection.fetchMoments returns PHFetchResult<PHAssetCollection> here PHAssetCollection is the ObjectType for the PHFetchResult. You got the ambiguous error because you have not specified the objectType.
A generic way to approach this.
class FetchPhoto {
class func assetCollection<T : PHObject>(result : PHFetchResult<T>) -> [T] {
var list : [T] = []
result.enumerateObjects(EnumerationOptions.concurrent) { (object, _, _) in
list.append(object)
}
return list
}
}
Swift 3
class PhotosHelper {
class func fetchAllLocalIdentifiersOfPhotos(completion : (_ localIdentifiers : [String]) -> ()) {
let photos : PHFetchResult<PHAsset> = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: nil)
photos.enumerateObjects ({ _,_,_ in
// Do your operations, you can see that there is no warnings/errors in this one
})
}
}