Effective algorithm to find the latest updated json - javascript

I receive some information by a request in javascript.
I have a json variable: var response for example.
Then each of them has an update date element:
response[0].updateDate
is the updateDate of the first element of my response.
How to find the element with the last updateDate?
I can do something like:
var actualElement = 0
for(var i = 0; i < response.length; i++){
if(response[actualElement].updateDate < response[i].updateDate){
actualElement = i;
}
}
Are you a more effective solution?

Sorting is not the fastest solution (though it's the prettiest), because it needs to iterate twice. If you just want the last, you can also use something like:
response.reduce((max, c) => max.updateDate > c.updateDate ? max : c, response[0]);
Thtat's if performance is a must for you.
PS. Or, without arrow functions:
response.reduce(function(max, c) {
return max.updateDate > c.updateDate ? max : c;
}, response[0]);

Just sort and get the first one
response.sort((a, b) => b.updateDate - a.updateDate)
response[0]

Since it is the strategy used by the UnderscoreJS library (widely used), I'd say it's the fastest.
It'd be even better if your server could order the array for you so you could know in advance the first element is the one you're looking for.

Related

how to optimize this traditional "for" loop for this case?

I'm playing with an Angular app, I have a method in a service that raises an HTTP get request to JSONplaceholder, and the response is an object array with 100 posts. I was wondering how can I render only 10 out of those 100 posts, and only could think about creating an auxiliary variable and do the following:
posts:any;
modified:any[] = [];
ngOnInit(): void {
this.dataService.getPosts().subscribe( res =>
{
this.posts = res;
for (let i = 0; i < this.posts.length; i++) {
i < 10 ? this.modified.push(this.posts[i]) : void(0);
}
}
)
}
This works, but I have to iterate the modified variable in my template, and I'm pretty sure there are better ways to improve this, with a better approach. How can this little code be a little better?
Thanks
Use array.slice - the function takes two parameters, 'start' and 'end'.
'end' signifies the index after the last item that you want (it is not inclusive of the 'end' index), and is optional. If 'end' is not supplied, you will get all elements starting at end and continuing to the end of the array.
So, in your case,
modified = posts.slice(0, 10);
just concerning the for loop you can do
for ( let i=0, len=this.posts.length; i<len; i++ ){
// code
}
this way you will only run this.posts.length once (this is just in case ths.posts has lots of data)
To handle arrays you can always check the JavaScript Array docs: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array
In this case you could use the slice method:
this.modified = res.slice(0,10);

Restricted JavaScript Array Pop Polyfill not working

I'm creating a few specific functions for a compiler I'm working on, But certain restrictions within the compiler's nature will prevent me from using native JavaScript methods like Array.prototype.pop() to perform array pops...
So I decided to try and write some rudimentary pseudo-code to try and mimic the process, and then base my final function off the pseudo-code... But my tests seem to fail... based on the compiler's current behavior, it will only allow me to use array.length, array element assignments and that's about it... My code is below...
pop2 = function(arr) {
if(arr.length>0){
for(var w=undefined,x=[],y=0,z=arr.length;y<=z;y++){
y+1<z?(x[y]=arr[y]):(w=arr[y],arr=x);
}
}
return w;
}
Arr = [-1,0,1,2];
// Testing...
console.log(pop2(Arr)); // undefined... should be 2
console.log(Arr); // [-1,0,1,2]... should be [-1,0,1]
I'm trying to mimic the nature of the pop function but can't seem to put my finger on what's causing the function to still provide undefined and the original array... undefined should only return if an initial empty array is sent, just like you would expect with a [].pop() call...
Anyone have any clues as to how I can tailor this code to mimic the pop correctly?
And while I have heard that arr.splice(array.length-1,1)[0]; may work... the compiler is currently not capable of determining splice or similar methods... Is it possible to do it using a variation of my code?
Thanks in advance...
You're really over-thinking [].pop(). As defined in the specs, the process for [].pop() is:
Get the length of the array
If the length is 0
return undefined
If length is more than 0
Get the item at length - 1
Reduce array.length by 1
Return item.
(... plus a few things that the JavaScript engine needs to do behind the scenes like call ToObject on the array or ensure the length is an unsigned 32-bit integer.)
This can be done with a function as simple as the one below, there's not even a need for a loop.
function pop(array) {
var length = array.length,
item;
if (length > 0) {
item = array[length - 1];
array.length -= 1;
}
return item;
}
Edit
I'm assuming that the issue with the compiler is that Array.prototype.pop isn't understood at all. Re-reading your post, it looks like arrays have a pop method, but the compiler can't work out whether the variable is an array or not. In that case, an even simpler version of this function would be this:
function pop(array) {
return Array.prototype.pop.call(array);
}
Try that first as it'll be slightly faster and more robust, if it works. It's also the pattern for any other array method that you may need to use.
With this modification, it works:
http://jsfiddle.net/vxxfxvpL/1/
pop2 = function(arr) {
if(arr.length>0){
for(var w=undefined,x=[],y=0,z=arr.length;y<=z;y++){
if(y+1<z) {
(x[y]=arr[y]);
} else {
(w=arr[y],arr=x);
break;
}
}
}
return w;
}
Arr = [-1,0,1,2];
// Testing...
console.log(pop2(Arr)); // 2
The problem now is to remove the last element. You should construct the original array again without last element. You will have problems with this because you can't modify the original array. That's why this tasks are maded with prototype (Array.prototype.pop2 maybe can help you)

_.findWhere from underscorejs to JQuery

I am trying to implement this code: http://jsfiddle.net/wQysh/351/ in my project.
Everything is fine except for the line:
t = _.findWhere(sc, { id : Number(a.trim()) });
They have used underscorejs and I want to translate this to JQuery without using another lib.
I went through the doc and it stated:
findWhere_.findWhere(list, properties)
Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
If no match is found, or if list is empty, undefined will be returned.
But still I am confused about this since I am not sure what to return exactly (as first value). Can anyone give me a JQuery alternative to that line?
Thanks in advance..
If you don't the generic nature of _.findWhere() you can use a simple while loop, and compare the id to the numeric value of a (fiddle):
t = 0; // t is used as a counter
aValue = Number(a.trim()); // assign the value to a variable instead of iterating it
while (t < sc.length && sc[t].id !== aValue) { t++; }; // find the index where the id is the as the aValue
t < sc.length && toSet.push(sc[t]); // if t is less the sc.length we found the item in the array
If you need a findWhere without underscore try this gist.
I also used this example in my project. And also needed use JQuery instead of Underscore.
Here is my solution:
t = sc.filter(function (el) { return el.id === a });
It work perfect for me;
If you use number for ids, you can also convert a to integer
t = sc.filter(function (el) { return el.id === parseInt(a, 10) });

Detecting how many different types of values in in an array

I know I could use variations of this answer to find out how many different types of data there are in an array:
How to count the number of certain element in an array?
But, what I am looking for is whether there is a simple way to count how many different types of data there are in an array:
I have arrays which may have 0, 1, or 2 as values
so it could be:
a = [1,2,0,1,1,1];
or they may all be the same and a different length:
a = [1,1,1,1,1,1,1,1,1,1,1,1,1];
In javascript, I would like a function that returns "1" if all values are the same, "2" if there is a mixture of just two of the possible values, and if the array contains all three values, "3".
Any help appreciated. Thanks.
The simple approach is to keep a map of found values, and remember every time you add to it: Live Example | Live Source
function countUniques(a) {
var valuesSeen = {};
var count = 0;
a.forEach(function(value) {
if (!valuesSeen[value]) {
++count;
valuesSeen[value] = true;
}
});
return count;
}
(Note: That uses ES5's forEach. If you're using an old browser, you'll need to shim that, search for "ES5 shim" to find a shim for it.)
Or if you don't like the people you work with very much and love using operators instead of branching statements: Live Copy | Live Source
function countUniques(a) {
var valuesSeen = {}, count = 0;
a.forEach(function(value) {
valuesSeen[value] || (++count, valuesSeen[value] = true);
});
return count;
}
Just for fun, here's a "funkier" (and somewhat obfuscated) solution using .reduce that requires no local variables:
function countUniques(a) {
return a.reduce(function(p, v) {
p.c += !(v in p.s); p.s[v] = 1; return p;
}, {c:0, s:{}}).c;
}
It's functionally identical to TJC's answer, except that the valuesSeen and count values are passed around as an object p as the "previous" value passed from the prior iteration of .reduce. The p.c element is equivalent to TJC's count and p.s is valuesSeen.
Note that .reduce (like .forEach) is an ES5 function which will require a shim on older browsers.

generate array in javascript

I am trying to generate a 2D n*m array in javascript full of zeros. What is the fastest way of doing that?
I know the simple for loop would be enough to set all the elements to 0, but what I would like to know, why can't I do that with mapping. For example with the underscore lib (or even the native map)
_.map(Array(n),function(a){return 0}) // makes {undefined,undefined,...}
while
_.map([1,2,3,5,6],function(a){return 0}) // makes {0,0,0,0,0}
Can anyone explain if I can fill an empty array with a map function and how, or why not?
PS: There is a trivial solution to my problem, I am just asking this cause I would like to learn more, and I cant find a good enough answer on google. Thank you
Typical JavaScript .map() functions ignore array members that are undefined. That's why Array(n) doesn't work.
You could easily add a method to Array.prototype to do a quick fill...
Array.prototype.fill = function(n,v) {
n = n || this.length;
for( var i = 0; i < n; i++ )
this[i] = v === void 0 ? i : v;
return this;
};
then...
Array().fill(3); // [0,1,2]
Array().fill(3, 0); // [0,0,0]
A simple trick may be:
var myarr = '0000000000'.split('');
Another is to make your own map Array extension, to be able to work with Array(n):
Array.prototype.mapx = function(callback){
return this.join(',').split(',').map(callback);
}
//usage
Array(5).mapx(function(){return 0;}); //=> [0,0,0,0,0]
I'd think the first one is the fastest, but no time (now) to test it.

Categories

Resources