Javascript create array in for loop - javascript

I'm pretty sure this is a basic question but my PHP background is making me unable to solve this. I was also unable to find a solution that came even close in SO.
I have an array of objects containing a value I want to loop and sum. Everything works well but I would like to directly sum those values to another array in the output.
So this is the working function:
function postsCalc(arrayEntry) {
var postsOutput = [];
var postLikes = 0;
for (var i = 0, len = arrayEntry.length; i < len; i++) {
postLikes += arrayEntry[i].likes.summary.total_count;
}
postsOutput.likes = postLikes;
return postsOutput;
}
Output:
likes : 55555;
Which works well, but can't I push it directly to the array key and avoid having to do the postsOutput.likes = postLikes?
Like this:
function postsCalc(arrayEntry) {
var postsOutput = [];
for (var i = 0, len = arrayEntry.length; i < len; i++) {
postsOutput.likes += arrayEntry[i].likes.summary.total_count;
// or even a multidimensional:
postsOutput.totals.likes += arrayEntry[i].likes.summary.total_count;
}
return postsOutput;
}
and that would output the same as above but avoiding the extra step, is this possible in Javascript?
Thanks in advance

You can use the reduce function on a list to do this:
function postsCalc(arrayEntry) {
var postLikes = arrayEntry.reduce(function(a, b) {return a + b.likes.summary.total_count}, 0);
return {likes: postLikes};
}
It works like this: Array.reduce(callback, initialValue) where callback = function(a, b) where a is the accumulator (e.g. tracks the sum, etc) and b is a representation of the item you're iterating over on the list. initialValue is the starting point for the function (e.g. on the first iteration).

Idiomatic javascript would look like (for your first function):
function postsCalc(arrayEntry) {
var postsOutput = {
postLikes: 0
};
for (var i = 0, len = arrayEntry.length; i < len; i++) {
postsOutput.postLikes += arrayEntry[i].likes.summary.total_count;
}
return postsOutput;
}
or, now that we can assume .forEach exists:
function postsCalc(arrayEntry) {
var postsOutput = {
postLikes: 0
};
arrayEntry.forEach(function(entry) {
postsOutput.postLikes += entry.likes.summary.total_count;
}
return postsOutput;
}

Related

How to chop a large array into smaller chunks of fixed length

I've a Float32Array of 10659503 elements in length. I want to chunk (split) it into small arrays of fixed length. How to do that? I've tried the method bellow it's not working:
var LENGTH = 4096;
var chunking = function(data) {
var chunks = [];
for (var i = 0; i < data.length; i += LENGTH) {
var index = ~~(i/LENGTH);
var offset = i%LENGTH;
if (offset === 0) {
chunks[i] = data.subarray(i, LENGTH);
}
}
console.log(chunks);
}
Thank you,
You can use Float32Array.subarray() get the sliced view of the original array.
function chunking(data, length) {
var result = [];
for (var i = 0; i < data.length; i += length) {
result.push(data.subarray(i, i + length));
}
return result;
}
console.log(chunking(new Float32Array(100), 12));
In general case I would do it using splice
function chunk(data, LENGTH) {
var ret = []
while (data.length) {
ret.push(data.splice(0,LENGTH))
}
return ret
}
But since Float32Array doesn't have this method in prototype (thanks #Felix Kling), it is going to be little bit more complicated:
function chunk(data, LENGTH) {
var ret = []
while (data.length) {
ret.push([].splice.call(data, 0, LENGTH))
}
return ret
}
However, since you probably want to avoid coping data back and forth in memory, you have to use methods that just create new ArrayBufferView without moving actual data. And that is exactly what subarray method is doing. So #thefourtheye answer is the right way to go.
Try this:
newArray = (function(array, chunk) {
retArr = [];
for (var i = 0; i < array.length; i+=chunk)
retArr.push(array.slice(i,i+chunk));
return retArr;
}(oldArray, chunkSize))
http://jsfiddle.net/R3Ume/7/

How to prototype a duplicate prototype method for Array in javascript

I'm trying to implement a duplicate method to the js Array prototype which concats a duplicate of the array to itself like so:
[11,22,3,34,5,26,7,8,9].duplicate(); // [11,22,3,34,5,26,7,8,9,11,22,3,34,5,26,7,8,9]
Here's what I have, but it causes the browser to crash:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var j = this.length;
for(var i = 0; i < this.length; i++) {
this[j] = this[i];
j++;
}
return this;
}
I'm trying to do this using native JS as practice for iterations and algorithms so I'm trying to avoid built-in methods, if possible, so that I can get a clearer understanding of how things are being moved around.
Any ideas on why it is crashing and how I can optimize it?
The code inside the loop changes the length of the array, so it will just keep growing and you will never reach the end of it. Get the initial length of the array in a variable and use in the loop condition. You can use that as offset for the target index also instead of another counter:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var len = this.length;
for (var i = 0; i < len; i++) {
this[len + i] = this[i];
}
return this;
}
The length of the array is increasing with each element added so you can not use this as a terminator. Try this.
var j = this.length;
for(var i = 0; i < j; i++) {
this[i+j] = this[i];
}
Here's simplest code
Array.prototype.duplicate = function () {
var array = this;
return array.concat(array);
};
Using Spread syntax;
In a method, this refers to the owner object.
Array.prototype.duplicate = function () {
return [...this, ...this]
};
let array = [1,2,3,4,5];
Array.prototype.duplicate = function () {
return [...this, ...this]
};
console.log(array.duplicate());

Abstract function to sum elements of an Array

I have like 40 different arrays and I want to find the average value of each of them.
In order to do it with each one, I have this code:
var SumArray1 = 0;
var avgArray1 = 0;
$.each(array1,function() {
SumArray1 += this;
avgArray1 = (SumArray1)/(array1.length);
});
But as I have those 40 arrays, I was trying to look for a way to make that function abstract, but I don't know how to introduce parameters for a function using $.each and I don't think having forty functions would be the right thing to do...
Thanks!
Your implementation calculates the average each time, but it only gets a correct value the last time. This is not necesary.
Also, there's no need to use $.each, which forces you to use an additional closure (my previous statement about waiting was wrong, since $.each is synchronous).
The following is simpler:
function avgArray(array) {
var i,l,s = 0;
for (i=0,l=array.length; i<l; i++) s+= array[i];
return s/l;
}
Add this code:
Array.prototype.average = function() {
var s = 0;
for(var i = 0; i < this.length; ++i) {
s += this[i];
}
return s/this.length;
}
Then at any point you can do something like
var myArray = [1,2,3,4];
var calculatedAverage = myArray.average(); // This will equal 2.5
Arrays have a built in reduce function, if you like short one-liners you can also do this:
var arr = [1,2,3,4];
function sum(x,y){
return x + y;
}
var total = arr.reduce(sum); // total -> 10
// This also works
var total = arr.reduce( function(x,y) { return (x + y); } );
var avg = ( total / arr.length );
Reduce is a higher-order function that 'reduces' an sequence into a single value.
Here is the execution flow of reduce.
var temp = sum( arr[0], arr[1] );
temp = sum( temp, arr[2] );
temp = sum( temp, arr[3] );
return temp;
Stealing Andrew Shepherd answer for adding new functions to the Array data structure.
Array.prototype.sum = function() { return this.reduce( function(x,y) { return (x+y); } )};
Array.prototype.avg = function() { return (this.sum() / this.length) };

Count how many strings in an array have duplicates in the same array [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Array value count javascript
I have an array which contains several duplicates, what I'm trying to achieve is to count how many duplicates each unique string has in this one array.
The array looks something like this
array = ['aa','bb','cc','aa','ss','aa','bb'];
Thus I would like to do something like this
if (xWordOccurrences >= 5) {
// do something
}
But I'm not sure how I would code this.
I was thinking, create an object with each unique string, then loop through the original array, match each string with it's object and increment it's number by 1, then loop over the object to see which words had the most duplicates...
But this seems like an over complexe way to do it.
You can use an object which has keys of the Array's values and do something like this
// count everything
function getCounts(arr) {
var i = arr.length, // var to loop over
obj = {}; // obj to store results
while (i) obj[arr[--i]] = (obj[arr[i]] || 0) + 1; // count occurrences
return obj;
}
// get specific from everything
function getCount(word, arr) {
return getCounts(arr)[word] || 0;
}
getCount('aa', ['aa','bb','cc','aa','ss','aa','bb']);
// 3
If you only ever want to get one, then it'd be more a bit more efficient to use a modified version of getCounts which looks similar to getCount, I'll call it getCount2
function getCount2(word, arr) {
var i = arr.length, // var to loop over
j = 0; // number of hits
while (i) if (arr[--i] === word) ++j; // count occurance
return j;
}
getCount2('aa', ['aa','bb','cc','aa','ss','aa','bb']);
// 3
Try this function:
var countOccurrences = function(arr,value){
var len = arr.length;
var occur = 0;
for(var i=0;i<len;i++){
if(arr[i]===value){
occur++;
}
}
return occur;
}
var count = countOccurrences(['aaa','bbb','ccc','bbb','ddd'],'bbb'); //2
If you want, you can also add this function to the Array prototype:
Array.prototype.countOccurrences = function(value){
var len = this.length;
var occur = 0;
for(var i=0;i<len;i++){
if(this[i]===value){
occur++;
}
}
return occur;
}
How about you build an object with named property?
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var summary = {};
var item = '';
for ( i in array){
item = array[i];
if(summary[item]){
summary[item] += 1;
}
else{
summary[item] = 1;
}
}
console.log( summary );
summary will contain like this
{aa: 3, bb: 2, cc: 1, ss: 1}
which you could then iterate on and then sort them later on if needed.
finally to get your count, you could use this summary['aa']
<script type="text/javascript">
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var myMap = {};
for(i = 0; i < array.length; i++) {
var count = myMap[array[i]];
if(count != null) {
count++;
} else {
count = 1;
}
myMap[array[i]] = count;
}
// at this point in the script, the map now contains each unique array item and a count of its entries
</script>
Hope this solves your problem
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var dups = {};
for (var i = 0, l = array.length; i < l; i++ ) {
dups[array[i]] = [];
}
for (str in dups) {
for (var i = 0, l = array.length; i < l; i++ ) {
if (str === array[i]) {
dups[str].push(str);
}
}
}
for (str in dups) {
console.log(str + ' has ' + (dups[str].length - 1) + ' duplicate(s)');
}
This function may do everything you need.
function countDupStr(arr, specifier) {
var count = {}, total = 0;
arr.forEach(function (v) {
count[v] = (count[v] || 0) + 1;
});
if(typeof specifier !== 'undefined') {
return count[specifier] - 1;
}
Object.keys(count).forEach(function (k) {
total += count[k] - 1;
});
return total;
}
Each value in the array is assigned and incremented to the count object. Whether or not a specifier was passed, the function will return duplicates of that specific string or the total number of duplicates. Note that this particular technique will only work on string-coercible values inside your arrays, as Javascript can only index objects by string.
What this means is that during object assignment, the keys will normalize down to strings and cannot be relied upon for uniqueness. That is to say, this function wouldn't be able to discern the difference between duplicates of 3 and '3'. To give an example, if I were to perform:
var o = {}, t = {};
o[t] = 1;
console.log(o);
The key used in place of t would eventually be t.toString(), thus resulting in the perhaps surprising object of {'[object Object]': 1}. Just something to keep in mind when working with Javascript properties.
I saw this post about it, perhaps it can help:
http://ryanbosinger.com/blog/2011/javascript-count-duplicates-in-an-array/

Create an array and check against it

I am not sure of how to do this, but what I want to do it create an array and be able to add new items to this array. Since the items are supposed to be a random number, when a new instance is created I would like it to be checked against the rest of the array and be sure that the number it has generated is not already in the array. How would I accomplish something like this?
I looked at Šime Vidas's answer and it seems to work, but I tried to shorten it to
var arr = [];
function add(a) {
var n = ~~(Math.random() * 100);
for (var i = 0; i < a.length; i++) {
if ( a[i] === n) { a.push(n) }
}
}
for (var i=0; i<5; i++){
add(arr)
}
document.getElementById('output').innerHTML += arr;
and I don't understand why this wouldn't work. It does pretty much the same thing, correct?
var arr = [];
function add(a) {
var n = ~~(Math.random() * 1000);
!is(a, n) && a.push(n);
}
function is(a, n) {
for (var i = 0; i < a.length; i++) {
if ( a[i] === n ) { return true; }
}
return false;
}
The add function creates a random integer number between 0 and 1000, and adds it to the array.
The is function checks whether the n number is somewhere inside the a array.
Demo: http://jsfiddle.net/kHhMp/2/
Demo 2: http://jsfiddle.net/kHhMp/3/
(Demo 2 shows that a number will only be added to the array if it's not already in it.)
btw
!is(a, n) && a.push(n);
is a short form of this:
if ( is(a, n) == false ) { a.push(n); }
The number is added to the array only if is(a, n) returns false.
UPDATE
var arr = [];
function add(a) {
var n = ~~(Math.random() * 1000),
ok = true;
for (var i = 0; i < a.length; i++) {
if ( a[i] === n ) { ok = false; }
}
ok && a.push(n);
}
If you enjoy fast code and you have many items in your array, you should use an Object rather than an Array.
Instead of doing var my_array=[]; my_array.push(my_number), use var my_object = {}; my_object[my_number] = true to add items in your structure.
With that approach, you can easily check if a new number is already in there with an if (my_object[my_number]) { /* already there */ } else { /* not there yet */ }
Once you're done, you can extract the list of numbers as an array by either using var keys = Object.keys(my_object), or if that's not available, var keys=[],i=0;for (keys[i++] in my_object);, more or less.
You may extend the built in Array object for your needs.
Array.prototype.pushUnique = function(value) {
var len = this.length;
for(var i = 0; i < len; i++) {
if(this[i]===value) return;
}
this.push(value);
}
var uniques = new Array();
uniques.pushUnique(1);
uniques.pushUnique(2);
uniques.pushUnique(1);
// array will contain only 1 and 2
The fastest, most cross-browser way is to iterate over the array using a loop:
var arr = [];
function addNum(num) {
for (i = 0, len = arr.length; i < len; i++) {
if ( arr[i] === num ) { return false; }
}
arr.push(num);
}
Be sure to get the length of the array before you run the loop so the length property isn't constantly checked.
var array = []
array[0] = 'Item'
array[0] === undefined
# returns false
array[1] === undefined
# returns true

Categories