How to reference an Object based on a Key Value? - oop

I have an array of objects: [obj1, obj2, obj3]
obj1 = {id:1,name:First}
obj2 = {id:2,name:Second}
...
But the object's array indexes are constantly changing. How else can I reference a specific object given only its id property? The goal is to set a variable equal to the name property (e.g. obj1's name = First). In other words, how can I reference an object's property given the key to a different property?
Any help would be greatly appreciated! Thank you!

There is multiple ways to achieve this, it only depends on performance requirement. Here's a Stack Overflow thread that I think solve your question:
Find a value in an array of objects in Javascript
I am also adding my favorite solution here:
ES6 Array.prototype.find function
var id = 1;
var arr = [{...},...];
var obj = arr.find(o => o.id === id);

Related

Kotlin: Should mutableList be declared as Val or Var?

I am reading through the existing codebase for my team, and I notice mutableListOf are always declared as val. In some scenarios, elements are added to the mutableListOf only once. E.g
val jobList = mutableListOf<JobActivity>()
jobList.addAll(job.activities)
In other scenarios, elements are added to mutableListOf in a loop. E.g
val jobList = mutableListOf<JobActivity>()
newJobList.filterScanType(retrieveJobType(JobContext.NEW)).forEach {
jobList.add(it)
}
Since the list is not initialized on creation, why not declare mutableListOf as var? A lot of examples found online also follow the same pattern of declaring mutableListOf as val.
Which is best to use in the 2 scenarios described, val or var?
I think it's declared as val because the list will be the same always, the only thing that changes is it's elements. You'll never do something like:
joblist = anotherList
And as #Taseer said, the properties of the object can be changed even if it's a val. For example:
data class Example(var name: String)
val exampleObject = Example("SomeName")
You'll still be able to do this:
exampleObject.name = "AnotherName"
But you can't do this:
exampleObject = anotherObject
The general rule of thumb while using Kotlin.
Difference in val and var
You may already know the differences but for the sake of an answer, I will repeat it. var lets you modify the reference of an object while val does not permit to change the reference of an object.
An object can be declared safely using either var or val keyword but the reason why you want to use val on an object(in most cases) is that you don't want to refer that class member with a new reference of a new instance of an object. That way, you always keep a reference to the original object and you can modify object properties.
In the case of var, though nothing wrong with it, you can still use it 'without' any problems. You can still access the object properties and modify them and also you will be able to refer that class member to a reference of a new object.
Example:
val myObject = MyObject()
myObject.something = 1 //can still modify object property.
myOjbect = MyObject() //re-referencing the object, NOT POSSIBLE
var myNewObject = MyNewObject()
myNewObject.someThing = "Hello world!" //can still modify object properties
myNewObject = MyNewObject() //can still reference it.
Why to use val over var in case of 'immutable' objects?
It gives you the security of not 'accidentally' placing a new reference.
But is there any performance benefit using val?
Answer: Final keyword benefit
val is more idiomatic for the reasons given in other answers and comments.
You said the val is not instantiated, but in your example code, it is.
val jobList = mutableListOf<JobActivity>()
is a factory that instantiates an empty MutableList<JobActivity>
Using this pattern (val not var, instantiated upon declaration) ensures that your code will never find an uninitialized or null value for jobList; and the compiler can prove it.
In short - there are no rules, its up to you
if you use val you can modify mutableList, but not reassign
if you need reassign another list to same variable, use var. In most cases you dont need it, thats why your team uses it frequently
Whether a variable is var or val distinguishes between a variable of which the value (reference) can be changed (var = mutable) or not (val = immutable).
You should always strive to use val over var to avoid unwanted side-effects (changing it in another thread for example).
In case of the MutableList you should most likely use a val, because you don't want to mutate the reference to the list but rather its contents.
Here an overview of your options:
// Do you want to change its reference (r) / contents (c)?
var a = mutableListOf(1, 2, 3) // r = yes, c = yes
var b = listOf(1, 2, 3) // r = yes, c = no
val c = mutableListOf(1, 2, 3) // r = no, c = yes
val d = listOf(1, 2, 3) // r = no, c = no
You create a variable with var that is mutable (that can change). Mutable means variable can be changed in future.
val is used when variable will not be changed in future that means constant or final.
Here changed means new value or new things will be assigned to the variable but
val list = mutableListOf()
in this list variable you assigned mutable list. You just changed the value of the list. But you didn't assign new instance or new value to the variable you just added and remove value from the list. That's it. So here list is immutable itself.
It will be mutable if you do things like below...
var list = mutableListOf()
list = mutableListOf()
Two initialization on the same variable.

How do I pass parameter of inline new object?

I have a method that accepts a string as a parameter.
The string I need to pass is the property of an instantiated object.
I don't need the object to stick around once I get the value of that property.
I know I can do this like so:
Dim x As New myClass1
foo.thing1 = MyMethod(x.Name)
x = New MyClass2
foo.thing2 = MyMethod(x.Name)
'etc...
But I would prefer to do this inline if possible, since I have to do this several times in a row with different MyClass types.
EDIT:
Figured it out:
foo.thing = MyMethod(new MyClass().Name)
Try
foo.thing1 = MyMethod((New myClass1).Name)
foo.thing2 = MyMethod((New MyClass2).Name)
You need the braces around New myClass1, otherwise VB thinks you are trying to create an object of type myClass1.Name, which, of course, does not exist.
foo.thing = MyMethod(new MyClass().Name)

F# Object constructor

After recently picking up a bit of C# after a long time of F#, I came to realise that 'object constructors' are a nice way of tricking oneself into believing they are dealing with a functional object.
Consider:
let x = new Something()
x.Key <- 1
x.Value <- 2
This feels very unclean because of the very obvious mutation of values. Especially if we keep our objects write once, it feels very unnecessary In C#, it is possible to initialise the object like this:
var x = new Something() { Key = 1, Value = 2 };
This looks nicer and actually it felt like I was using a record (almost), obviously its just sugar but its nice sugar.
Q. Assuming we have no control over `Something' (pretend its from some C# library), is it possible, in F# to use this shorthand initialisation, if not, why?
Yes, you can do that. It would look something like this:
let x = new Something(Key = 1, Value = 2)
The syntax is detailed in Constructors (F#) under the section "Assigning Values to Properties at Initialization".
Yes, F# support use cases similar to C# object initializers but F# approach is somewhat more generic.
F# specification 14.4 Method Application Resolution says:
(after method is successfully resolved) Build the resulting elaborated expression by following these steps:
For each NamedActualArgs whose target is a settable property or field, assign the value into the
property.
meaning that you can do things that C# doesn't allow
type Something() =
member val Key = 0 with get,set
member val Value = "" with get,set
static member Create() = Something()
let a = Something(Key = 1, Value = "1") // create instance with constructor, set properties afterwards
let b = Something.Create(Key = 1, Value = "1") // create instance using factory method, set properties afterwards

How to create a Dictionary with for value type that is known?

I want to create a Dictionary where the Key type is Integer and the Value type is the type of the class I am currently executing in.
I've tried the following:
Dim col as new Dictionary(Of Integer, Me.GetType())
but I am getting an error stating that `keyword does not name a type.
How do I create a dictionary based on the type of the executing class?
C# sample of creating dictionary of int to a type.
Methods used:
Type.MakeGenericType
Type.GetConstructor
ConstructorInfo.Invoke
The problem is mainly to express resulting type in somewhat type-safe manner. In Dictionary case one may resort to IDictionary, or continue to use reflection to manipulate objects.
It may also be possible to somehow express most manipulation with generic code which is invoked by more reflection with MakeGenericMethod
Sample:
var myType = typeof(Guid); // some type
// get type of future dictionary
Type generic = typeof(Dictionary<,>);
Type[] typeArgs = { typeof(int), myType };
var concrete = generic.MakeGenericType(typeArgs);
// get and call constructor
var constructor = concrete.GetConstructor(new Type[0]);
var dictionary = (IDictionary)constructor.Invoke(new object[0]);
// use non-generic version of interface to add items
dictionary.Add(5, new Guid());
Console.Write(dictionary[5]);
// trying to add item of wrong type will obviously fail
// dictionary.Add(6, "test");
Just use the class name Dim col as new Dictionary(Of Integer, MyClass)
On a side not using integer as your key can get confusing since a dictionary also uses integer for the index. If the keys are to be consecutive integers, you might be better served by a list.

flex 3 iterate through object values

i have an object which represents a database table. I want to iterate through this object and print printing each value. What can i use to do this?
i want to do this inside my mxml not actionscript
for each object attribute i want to create an imput field
Look up the documentation on Flex 3 looping. If you do, you'll find this:
for..in
The for..in loop iterates through the properties of an object, or the elements of an array. For example, you can use a for..in loop to iterate through the properties of a generic object (object properties are not kept in any particular order, so properties may appear in a seemingly random order):
var myObj:Object = {x:20, y:30};
for (var i:String in myObj)
{
trace(i + ": " + myObj[i]);
}
// output:
// x: 20
// y: 30
Instead of trying to create an input field for each object, I'd suggest you take a look at DataGrid and custom ItemEditors.
I agree that this answer isn't useful. It only works with generic objects, not user declared
objects.
However, here's some code that should/could work using the describeType as suggested above. (And I don't really think it's too complex). Be aware that only public properties/methods, etc. are exposed:
var ct:CustomObject = new CustomObject();
var xml:XML = describeType(ct);
for each(var accessor in xml..accessor) {
var name:String = accessor.#name;
var type.String = accessor.#type;
trace(ct[name]);
}
The problem with "for...in" is that it iterates only on dynamic properties. That is, if your object is defined as a Class (and not dynamically), "for..in" won't give anything.
The ActionScript documentation suggest to use describeType() for fixed properties, but it looks over-complicated for this simple taskā€¦
You can write it like actionscript but include it inside the mxml file with the script tag:
<mx:Script>
<![CDATA[
public function LoopAndPrint() : void
{
//your code here
}
]]>
</mx:Script>