Javascript Map.set at position - javascript

Is there any way that I can insert an new element into a Map before of or after an existing key?
as for Array would be: arr.splice(<POSITION>, 0, <NEW ELEMENT>);
Thanks!

general theory
A Map does –unlike an array– not have the semantics of “order”.
It's designed to be most efficient for storing&retrieving values for specific keys. (In fact, it's internal implementation does some structuring/ordering specifically optimized for that, “b-tree” being the keyword here.
javascript implementation
Despite all that, mozilla docs say:
A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration.
update: The official ECMA-262 standard confirms this.
personally, I am guessing, implementors will keep a separate index for order-of-entry and a b-tree for most efficient singular access.
Based on this, what you would have to do is essentially, treating the map like an immutable object, and creating a new one from it:
iterate over the prior map
add each element to a new map. – when the right time comes, insert your element. – Keep iterating for the rest of it
assign your new element to the name of the old one.
I don't now your specific use case, but perhaps your problems could also be solved by sort Iteration to specific criteria right when iterating over it.

Related

Should I use array methods like map and filter, if I'm not going to return anything?

In the last year I've been using array methods like map and filter more often instead of the standard for loop on an array. It feels simpler to read and write, and does all the things I'm most likely going to do anyway, like create a local variable.
Often times I don't return anything though. Eslint doesn't like me very much though. According to them, they say you always need a return, otherwise its "probably a mistake"
https://eslint.org/docs/rules/array-callback-return
Why? Is just good practice? What are downsides of a return-less array method?
Been thinking on this for a while. Any insight or thoughts would be great.
Should I use array methods like map and filter, if I'm not going to return anything?
No, you should not.
Why? Is just good practice?
Yes. It is a good practice to use the appropriate iteration method for the type of iteration you are doing. There are numerous ways to iterate for a reason. Pick the appropriate mechanism.
What are downsides of a return-less array method?
Using .map() and .filter() without actually returning anything from the callback have the following downsides:
Your code is misleading. The point of .map() and .filter() is to iterate over the array and produce a new array. When a developer reads some code and sees .map() or .filter() being used, they expect that there should be a returned array. When they don't see it being done that way, they will be confused, will initially feel like they don't understand the code. If I were doing a code review on code like this, I would not approve of code like this.
Your code unnecessarily creates objects that are not used. That's just wasteful and is not a good practice. Instead, use an iteration method that does not produce an output array such as for/of, a regular for loop or .forEach().
Your code won't lint. Linters provide objections to things for a reason. Using .map() or .filter() without returning anything from the callback is, just as the linter says, "probably a programming mistake" because that is not how those functions are designed to be used and there are appropriate alternatives when you don't want a returned array.
So, if you're just trying to do an iteration without creating any resulting array, use for/of or .forEach() or some other iteration scheme that isn't specifically designed to create an output array that you don't want.
First you need to know about the difference between Map/Filter and forEach.
resuming.. forEach is mostly used when you want iterate an array with/as a procedure. check
Map and Filter are related to a callback function applied on every iteration.
The return statement of those is what is going to be evaluated, not the function By the Map/Filter function at the end. Reason why it's needed. Althought JS allows "whatever" And of course you are able to define that function what comes to our understanding as "The filter".
For Filter you can see that "true" and "false" as when the "data" is going to be filtered or not.
basically you can loop with map or forEach/for, the difference are the following:
foreach: This iterates over a list and applies some operation with side effects to each list member, this means that you are transforming THE CURRENT ARRAY you are looping.... or as noticed by #TiagoCoelho, you dont mess with the array at all, just loop thought it.
map: This iterates over a list, transforms each member of that list, and returns another list of the same size with the transformed members, this means that you will get a BRAND NEW ARRAY with the modified items and you will also have in memory your old array.
so basically it depends on what you want to do with the data inside of your array.
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
examples:
var a = [1, 2, 3, 4];
var b = [1, 2, 3, 4];
//multiply each item for 2, it will stay on the same array.
a.forEach(i => {
i = i * 2
})
//multiply the items of B for 2 but it will return a new array
var c = b.map(i => {
return i * 2
})
console.log(a); //modified reference
console.log(b); //stays the same
console.log(c); //new array

Remove object in array using filter and splice which one is best approach in JavaScript?

Hi I delete an object in an array using two approaches:-
splice and filter.
splice code here:-
(this.myArray).splice((this.myArray).indexOf(myobject), 1);
filter code here:-
(this.myArray).filter(obj => obj !== myobject);
Please tell us differences between both and which one is the best approach?
I think chrystian's answer is the right one but I want to add a warning (not related to performance but to avoid a potential undesired bug)
WARNING: One small detail, be careful when you use splice with indexOf. If indexOf returns (-1), that's to say the element wasn't found, splice will remove the last element of the array (negative indexing works).
If you decide to use splice instead of filter take that into consideration and check for the indexOf result before doing splice
I think that the main difference here is:
splice - lets you remove an element from this particular array
filter - won't touch the input array and will create and return new filttered array
angular has nothing to do here and when it comes to speed, splice will win
and small test as proof https://jsperf.com/array-splice-vs-array-filter/1
In case you know the index using splice would be an O(1) operation while using filter is an O(n) operation.
Array.splice - will change the Array itself. (use: myArray.splice)
Array.filter - will return the filtered Array. (use: myFilteredArray = Array.filter)
This is a test result on an Array of 30 small objects. I ran it on jsbence.me:
There are several answers regarding performance, but there is another difference that wasn't explicitly mentioned between the two methods you are asking about:
The first method you wrote, using indexOf, will only splice the first reference to myobject in this.myArray, as it says in the documentation,
The indexOf() method returns the first index at which a given element can be found
The second method you asked about using filter, will remove every reference to myobject in this.myArray, in the case that you have multiple references to it in the array. Here is the line from filter's documentation that explains it:
Filter() calls a provided callback function once for each element in
an array
And as chrystian said, filter also returns a new array, whereas splice modifies the array it was called on. For clarity, I've written a little gist that shows overloads of both options side-by-side. It has pretty clear documentation about the differences, so feel free to use it if it helps you at all. (If you prefer it as a prototype method, as some people do, here's that as well.) Since this question is specifically about Angular, the gists are in Typescript.
The second part of your question asked which was best. The best approach may be situationally based on two things:
How many times is myobject referenced in this.myArray?
If it occurs many times, and you want to remove all references, use filter
If it occurs many times, and you only want to remove the first reference, use indexOf
If it occurs only once, ask yourself question 2:
Is performance a big concern?
If it is, then do a benchmark for it using the engine that will be running the script, and use the most performant method
If it isn't, use the one you find easiest to read.

Dynamic property as key VS List of objects in Javascript - which one will be more efficient

I need a data structure something like HashMap(in JAVA) where I want map status of user using user id as a key . So I can easily create a map dynamically like this:-
var mapOfIdVsStatus = {
123: "true",
456: 'false'
}
alert(JSON.stringify(mapOfIdVsStatus));
In my scenario, new user id and status will be added/updated very frequently that is
Object.keys(mapOfIdVsStatus).length;
will increase. But this will help to search status of a user in a faster way.
I can do this in an alternative way like this:
var user1={
id:123,
status: true
}
var user2={
id:456,
status: false
}
var listOfUser = [];
listOfUser.push(user1);
listOfUser.push(user2);
alert(JSON.stringify(listOfUser));
I can also search status in the list for a user but need extra effort like looping..etc
Considering a lots of Add, Search and Memory Optimization which one will be my best choice?
Behaviors would be like:
Are keys usually unknown until run time? -YES
Do you need to look them up dynamically? - YES
Do all values have the same type? -YES
Can they be used interchangeably?- NO
Do you need keys that aren't strings? - Always String
Are key-value pairs often added or removed?- Always added, No removal
Do you have an arbitrary (easily changing) amount of key-value pairs?- YES
Is the collection iterated? - I want to avoid iteration for faster
access.
The best choice is an ES6 Map. MDN gives some hints when to use it instead of a plain object:
If you're still not sure which one to use, ask yourself the following questions:
Are keys usually unknown until run time? Do you need to look them up dynamically?
Do all values have the same type? Can they be used interchangeably?
Do you need keys that aren't strings?
Are key-value pairs often added or removed?
Do you have an arbitrary (easily changing) amount of key-value pairs?
Is the collection iterated?
If you answered 'yes' to any of those questions, that is a sign that you might want to use a Map.
The object, hands-down. Property lookup will be, at worst, a kind of hashmap-style lookup rather than a linear search.
If you do this, it's best to create the object without a prototype:
var mapOfIdVsStatus = Object.create(null);
...so it doesn't inherit properties from Object.prototype.
On ES2015-compliant JavaScript engines, you might also look at Map. Map is specifically designed to be a simple key/value map, and so is unencumbered by any object-ness. On Chrome and Firefox, at least in my simple test, it performs as well or better than object lookup with string keys (this is Chrome; Firefox seems to be similar):
...but object lookup easily outpaces Map with number keys (this is also Chrome, on Firefox it was only twice as fast, not just under three times as fast):
But, those tests only test querying values once they've been added, not the tumult of adding new ones. (The updates you're talking about wouldn't matter, as you're changing the properties on the stored objects, not the thing actually stored, if I'm reading right.)
One really key thing is that if you need to remove entries, with an object you're better off setting the property's value to null or undefined rather than using delete. Using delete on an object can really, really slow down subsequent operations on it.

Are native map, filter, etc. methods optimized to operate on a single intermediary array when possible?

Consider the below snippet, which converts an array of objects to an array of numbers, with negative values filtered out, and then doubled by 2:
var objects = (new Array(400)).fill({
value: Math.random() * 10 - 5
});
var positiveObjectValuesDoubled = objects.map(
item => item.value
).filter(
value => value > 0
).map(
value => value * 2
);
When chained together like this, how many actual Array objects are created in total? 1, or 3? (excluding the initial objects array).
In particular, I'm talking about the intermediary Array objects created by filter, and then by the second map call in the chain: considering these array objects are not explicitly referenced per se, are Javascript runtimes smart enough to optimize where possible in this case, to use the same memory area?
If this cannot be answered with a clear yes-or-no, how could I determine this in various browsers? (to the best of my knowledge, the array constructor can no longer be overridden, so that's not an option)
Good commentary so far, here's a summary answer: an engine might optimize for memory usage across chained method calls, but you should never count on an engine to do optimization for you.
As your example of chained methods is evaluated, the engine's memory heap is affected in the same order, step by step (MDN documentation on the event loop). But, how this works can depend on the engine...for some Array.map() might create a new array and garbage collect the old one before the next message executes, it might leave the old one hanging around until the space is needed again, it might change an array in place, whatever. The rabbithole for understanding this is very deep.
Can you test it? Sometimes! jQuery or javascript to find memory usage of page, this Google documentation are good places to start. Or you can just look at speed with something like http://jsperf.com/ which might give you at least an idea of how space-expensive something might be. But you could also use that time doing straightforward optimization in your own code. Probably a better call.

Javascript associative array modification during for loop

The javascript for keyword will iterate over all properties of an object. If the object is modified within the loop body, what happens?
For example, is the following code OK?
for(var key in obj)
if (whatever(obj[key]))
delete obj[key];
OK would be if this code works in a deterministic fashion and preferably that all keys in obj are tested exactly once. By contrast, in .NET or Java similar constructs will typically throw an exception.
I think it works. Just be careful to ask for hasOwnProperty(key) - because for will also happily iterate over inherited properties (and methods, which are just properties with function values).
Also: http://www.w3schools.com/js/js_loop_for_in.asp says:
Note: The code in the body of the for...in loop is executed once for each property.
Also: https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in says:
A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting). If a property is modified in one iteration and then visited at a later time, the value exposed by the loop will be its value at that later time. A property which is deleted before it has been visited will not then be visited later. Properties added to the object over which iteration is occurring may either be visited or omitted from iteration. In general it is best not to add, modify, or remove properties from the object during iteration, other than the property currently being visited; there is no guarantee whether or not an added property will be visited, whether a modified property will be visited before or after it is modified, or whether a deleted property will be visited before it is deleted.
What I read from this is - if you're modifying values other than the current one, the nondeterminism might bite you in the ass. However, modifying the current one should be okay.
It may be possible to modify an object's properties while iterating over them using for-in. The question is: should you care? It is easy to rewrite the code to first create a list of the properties and then to delete the ones that match the criteria for deletion.
If, for example, you wanted to delete certain properties that are not functions and are not inherited:
var keys = Object.keys(obj).filter(k=>!(obj[k] instanceof Function))
for(var key of keys)
if(whatever(obj[key]))
delete obj[key];
In general, it is better to write code that does not give rise to tricky questions like the one you raise.
Note that this code assumes the existence of Object.keys() in your runtime environment. Older browsers may not support this, so you may need to find a workaround if you need to support those.

Categories