AngularJS arrays, proto and .length - Why can't i get a valid number? - arrays

Sometimes you need to ng-if or ng-show an item in html based on some choices made earlier. One of these for me is "Additional Item". You can enter one set of information, and also if you want, an additional set. This creates an array of 2 similar objects. With this setup, you can only have 1 or 2 objects in this array. (important, since the scope of this question needs to be limited this way)
I want to ng-show an html directive based on "myItemsArray.length > 1". Since the array can (read should) only be 1 or 2 in length (not 0), this should work. However, it does not, because AngularJS seems to be adding an item "proto" to the array which adds to the count. See the image.
The problem is, proto makes the array length equal 2. I am not going to just look for length > 2 because i really don't know if i can count on proto always being there, and i just think thats bad practice anyway.
Also, i know there are MANY other ways of doing this (setting a boolean, or using another var to indicate etc, but i really just want to work with count of items in the array because "business logic"..
EDIT:
After doing a little debugging, i'm seeing that i have an array of "Object, undefined". How is this even possible :)
Some search lead me to this. Why are some values ​​in my array undefined
EDIT:
Seems that using a delete may cause this problem

Related

How do I access value of a selected <option> tag down 2 trees in a function?

PizzaBuilder1.js
Ingredients.js
Bases.js
PizzaBuilder2.js
PizzaBuilder3.js
I'll try to describe my issue in the least confusing way. So what I'm trying to achieve is create a function(pic4-PizzaBuilder2), where I compare the given key of this.state.ingredients.Bases (and other sub-objects, but that's not important for now) with value of selected option tag in Bases.js and when it matches, set the given value of that key to true. The hierarchy is like this: PizzaBuilder.js > Ingredients.js > Bases.js. I have already managed to match each option value with the key inside the object with the same name. However, what I'm still struggling with is how to access it in PizzaBuilder.js when the select option value I wanna compare it to is 2 trees down (see pic4-PizzaBuilder2, that is supposed to be const selectedOption, but I obviously still need to figure out how to access it). I'll be really grateful for any kind of advice.

Array constant in a formula with non-adjacent cell references

I need to add an array of non-adjacent cells to my array formula. I have tried all of the following array constant-like ways and they all give me a "There is a problem with this formula error".
'Chart Data'!{A12:A14,D3:D11}
{'Chart Data'!A12:A14,'Chart Data'!D3:D11}
'Chart Data'!{A12,A13,A14,D3:D11}
{'Chart Data'!A12,'Chart Data'!A13,'Chart Data'!A14,'Chart Data'!D3:D11}
'Chart Data'!{A12,A13,A14,D3,D4,D5,D6,D7,D8,D9,D10,D11}
{'Chart Data'!A12,'Chart Data'!A13,'Chart Data'!A14,'Chart Data'!D3,'Chart Data'!D4,'Chart Data'!D5,'Chart Data'!D6,'Chart Data'!D7,'Chart Data'!D8,'Chart Data'!D9,'Chart Data'!D10,'Chart Data'!D11}
Entire formula (the array constant goes where the {#####} is):
{=SUM(((1-References!M1:M12)*({#####}*(G3:G14+F3:F14-0.11)))+((References!M1:M12)*('Chart Data'!A12:A23*(G3:G14+F3:F14-0.11)))+((H2:H13*X3:X14)+(H3:H14*Y3:Y14)+(I2:I13*(V3:V14-X3:X14))+(I3:I14*(W3:W14-Y3:Y14))))}
I am 100% positive that it is this particular array constant that is causing the problem. I can't move the cells I'm referencing to put them in line. Is it even possible to reference a non-adjacent range in an array formula? If it's possible, what am I doing wrong?
There are several ways to do this. The following is very simple and pretty direct so my favorite.
EITHER choose a cell to build your string for your non-contiguous array in OR create a Named Range to do it. I'll show the first as it seems nicest for being able to use the mouse freely, but in both of them you can actually be creative using about how you build the string that will become your array. The main advantage of creating it in a Named Range is no helper cell lying about anywhere.
So, you create that string and then make it an array. Say you have a non-contiguous array needed using cells A12:A14 and C3:C11. You use joining and TEXTJOIN() like so:
="{"&TEXTJOIN(",",FALSE,B12:B14,C3:C11)&"}"
to create a text string of the values in those cells wrapped with the curly braces ({}) just as if you'd typed it in ("hardcoded it"). It will look like this with the right values in those cells:
{1,2,3,1,2,3,4,5,6,7,8,9}
but is ain't an array yet.
Now the magic in THIS method. Create a Named Range, perhaps called String2Array, and give it a formula of:
=EVALUATE(A1)
(or whatever cell you used for the above formula creating the text string that you want to be an array). Make the reference absolute. ($A$1... which it will do for you, just don't edit it to be relative. If you use this for similar work, but need it relative, that will work fine, but it just isn't what is needed here.)
Now replace your placeholder in the formula with the Named Range's name (perhaps you DID use String2Array). And you're done.
A couple other methods use INDEX() or CHOOSE() and you can force things to be arrays using the functions DOLLARDE() and IMREAL() (I found on a helpsite in a 2014 post) and some others do the same kind of thing. In those days, one had to use {CSE} too, but SPILL takes care of that now (with those two weird-seeming friendlies and at least two others). The poster was someone I've seen on this site, EXCELXOR was the name for the site, XOR LX was the name of the member here though the functions were mentioned in a comment by a Lori. Since he covers, it seems, aspects not usually covered in helpsites, looking up some of his work here, or elsewhere too, might be worthwhile to some folks.
But this method is very direct and therefore easy to maintain. And personally, I love the idea that EVALUATE() (must be used IN the Named Range functionality, not cell-side) is the gift that keeps on giving, one wonderfully helpful thing after another.
So many ways. You could even literally build the array in a helper column/row somewhere and reference THAT instead of the non-contiguous addresses. I like the joining+TEXTJOIN() approach best because I can use the mouse to easily get all the blocks into the formula since it is a LIVE formula. But you can type out a string fairly easily too and add the {}'s. Or perhaps a user would type a string of addresses and you'd add them like the formula does above. And you can insert actual values (constants) into the string you are building as well if that is appropriate. And you could build it formulaicly... I wouldn't pick that workload first thing off the pile of choices, but if you were going to do it anyway already, then... or if it's a small build.

Most efficient algorithm to convert array A into array B of unknown lengths

I have an array of indefinite length from which the user chooses to add/remove components. To reflect the changes in the backend I must perform ajax requests.
My question is what would be the most efficient way to reflect those changes?
Currently I have two approaches in mind:
1.) Find the differences between the two arrays and then appropriately address the differences by adding the missing / removing the extra elements one by one.
2.) Make use of the remove all service to remove every single item in the array in the backend using a single request then adding one by one whatever is in the second array.
At the first glance approach 1 seems to be better with small changes in particular. However if the user decides to remove 80 or so elements from the array and only add 2 more then approach 2 outclasses approach 1.
Perhaps there is a better solution?
Thanks!

Getting the first element in an array/any collection

So the other day I had my colleague review my code and he saw that I was using array[0], in Java terms this is basically getting the first element of the array. I did this several times for different purposes, all of which is to get the first element in an array/collection, for example list.get(0), to which he strongly disagreed with.
His argument was that somebody from non-programming background would have problem understanding it and using 0 in such cases is basically hard-coding, which is bad practice. I google-ed several times and all suggestions to getting the first element in an array or any collection is providing them the index, which is 0 in this case.
Could anyone provide me with a suggestion on getting the first element in a meaningful way?
Try using linkedlist's getfirst method to get the first element of the list.
If you were to use an ArrayList is backed by an array and hence its perfectly valid to use index as 0 to get first element.

Optional array vs. empty array in Swift

I have a simple Person class in Swift that looks about like this:
class Person {
var name = "John Doe"
var age = 18
var children = [Person]?
\\ init function goes here, but does not initialize children array
}
Instead of declaring children to be an optional array, I could simply declare it and initialize it as an empty array like this:
var children = [Person]()
I am trying to decide which approach is better. Declaring the array as an optional array means that it will not take up any memory at all, whereas an empty array has at least some memory allocated for it, correct? So using the optional array means that there will be at least some memory saving. I guess my first question is: Is there really any actual memory saving involved here, or are my assumptions about this incorrect?
On the other hand, if it is optional then each time I try to use it I will have to check to see if it is nil or not before adding or removing objects from it. So there will be be some loss of efficiency there (but not much, I imagine).
I kind of like the optional approach. Not every Person will have children, so why not let children be nil until the Person decides to settle down and raise a family?
At any rate, I would like to know if there are any other specific advantages or disadvantages to one approach or the other. It is a design question that will come up over and over again.
I'm going to make the opposite case from Yordi - an empty array just as clearly says "this Person has no children", and will save you a ton of hassle. children.isEmpty is an easy check for the existence of kids, and you won't ever have to unwrap or worry about an unexpected nil.
Also, as a note, declaring something as optional doesn't mean it takes zero space - it's the .None case of an Optional<Array<Person>>.
The ability to choose between an empty array or an optional gives us the ability to apply the one that better describe the data from a semantic point of view.
I would choose:
An empty array if the list can be empty, but it's a transient status and in the end it should have at least one element. Being non optional makes clear that the array should not be empty
An optional if it's possible for the list to be empty for the entire life cycle of the container entity. Being an optional makes clear that the array can be empty
Let me make some examples:
Purchase order with master and details (one detail per product): a purchase order can have 0 details, but that's a transient status, because it wouldn't make sense having a purchase order with 0 products
Person with children: a person can have no children for his entire life. It is not a transient status (although not permanent as well), but using an optional it's clear that it's legit for a person to have no children.
Note that my opinion is only about making the code more clear and self-explainatory - I don't think there is any significant difference in terms of performance, memory usage, etc. for choosing one option or the other.
Interestingly enough, we have recently had few discussions regarding this very same question at work.
Some suggest that there are subtle semantic differences. E.g. nil means a person has no children whatsoever, but then what does 0 mean? Does it mean "has children, the whole 0 of them"? Like I said, pure semantics "has 0 children" and "has no children" makes no difference when working with this model in code. In that case why not choosing more straightforwards and less guard-let-?-y approach?
Some suggest that keeping a nil there may be an indication that, for example, when fetching model from backend something went wrong and we got error instead of children. But I think model should not try to have this type of semantics and nil should not be used as indication of some error in the past.
I personally think that the model should be as dumb as possible and the dumbest option in this case is empty array.
Having an optional will make you drag that ? until the end of days and use guard let, if let or ?? over and over again.
You will have to have extra unwrapping logic for NSCoding implementation, you will have to do person.children?.count ?? 0 instead of straightforward person.children.count when you display that model in any view controller.
The final goal of all that manipulation is to display something on UI.
Would you really say
"This person has no children" and "This person has 0 children" for nil and empty array correspondingly? I hope you would not :)
Last Straw
Finally, and this is really the strongest argument I have
What is the type of subviews property of UIView: it's var subviews: [UIView] { get }
What is the type of children property of SKNode: it's var children: [SKNode] { get }
There's tons of examples like this in Cocoa framework: UIViewController::childViewControllers and more.
Even from pure Swift world: Dictionary::keys though this may be a bit far fetched.
Why is it OK for person to have nil children, but not for SKNode? For me the analogy is perfect. Hey, even the SKNode's method name is children :)
My view: there must be an obvious reason for keeping those arrays as optionals, like a really good one, otherwise empty array offers same semantics with less unwrapping.
The Last Last Straw
Finally, some references to very good articles, each of those
http://www.theswiftlearner.com/2015/05/08/empty-or-optional-arrays/
https://www.natashatherobot.com/ios-optional-vs-empty-data-source-swift/
In Natasha's post, you will find a link to NSHipster's blog post and in Swiftification paragraph you can read this:
For example, instead of marking NSArray return values as nullable, many APIs have been modified to return an empty array—semantically these have the same value (i.e., nothing), but a non-optional array is far simpler to work with
Sometimes there's a difference between something not existing and being empty.
Let's say we have an app where a user can modify a list of phone numbers and we save said modifications as modifiedPhoneNumberList. If no modification has ever occurred the array should be nil. If the user has modified the parsed numbers by deleting them all the array should be empty.
Empty means we're going to delete all the existing phone numbers, nil means we keep all the existing phone numbers. The difference matters here.
When we can't differentiate between a property being empty or not existing or it doesn't matter empty is the way to go. If a Person were to lose their only child we should simply have to remove that child and have an empty array rather than have to check if the count is 1 then set the entire array to nil.
I always use empty arrays.
In my humble opinion, the most important purpose of optionals in Swift is to safely wrap some value that may be nil. An array already act as this type of wrapper - you can ask the array if it has anything inside & access its value(s) safely with for loops, mapping, etc. Do we need to put a wrapper within a wrapper? I don't think so.
Swift is designed to take advantage of optional value's and optional unwrapping.
You could also declare the array as nil, as it will save you a very small (almost not noticable) amount of memory.
I would go with an optional array instead of an array that represents a nil value to keep Swift's Design Patterns happy :)
I also think
if let children = children {
}
looks nicer than :
if(children != nil){
}

Resources