how to sum an array of arrays in javascript - javascript

I currently have this function
function radius(d) {
return d.values[0].environment["4*"];
console.log(d);
}
However id liked to be able to average all of the 4* environment values for each document(there are 6 in the example below) and return this as the radius. Im new to JS so no idea how to do this. can you help. here is the structure of the data

You can use reduce function:
function radius(d) {
return d.values.reduce(function(avg, item, index, array) {
return avg + item.environtment['4*'] /array.length
},0)
}

It's tough to answer the question accurately without testing the whole data structure. Based on what you've provided this should work:
function radius(d) {
let sum = 0;
for (let i=0; i<d.length; i++) {
let num = parseInt(d[i].environment['4*']);
if (!isNaN(num)) sum += num;
}
return sum;
}
We loop through the array, and if environment['4*'] is a valid number we sum it up. Functionally it would be:
function radius(d) {
const filtered = d.values.filter((x) => {
let num = parseInt(x.environment['4*']);
return !isNaN(num);
});
const sum = filtered.reduce((acc, val) => {
return acc+val;
},0)
return sum/filtered.length;
}

Related

Problem when comparing array elements (Javascript)

Hey I have a small problem. So basically I'm passing string to function as an argument, then converting it to array and I'm trying to compare generated array elements with one another and if they are equal it should return ")" else "(", but there is problem when comparing elements and the values are wrong. Maybe someone could help me.
function duplicateEncode(word) {
let splitString = word.split("");
let newArr = splitString.map((val, index, arr) => {
for (let i = 0; i < splitString.length; i++) {
if (val === arr[i]) {
return ')';
} else {
return '(';
}
}
});
return newArr.join('');
}
Use Javascript's Map object to store if current letter exists or not.
function duplicateEncode(word){
let m = new Map();
let splitString= word.split("");
let coded = "";
splitString.map( s => {
if(!m[s]){
m[s] = true
coded += "("
} else {
coded += ")"
}
})
return coded
}
console.log(duplicateEncode("stack"))

Function trims values after being passed in another function

I would like have renderData() display the values from max. When I console.log(max) in calculateData() it displays all three maximum values from three JSON objects. However, when I return max in renderData() it only shows the first value. Why is this, and what can I do to make it display all three values instead of just one? Note: data is the json list of objects being passed. Thank you!
function calculateData(data) {
for (i in data) {
var arr = [];
var max;
var obj = data[i].tones;
obj.map(function(item) {
var data = item.score;
arr.push(data);
})
max = arr.reduce(function(a, b) {
return Math.max(a, b);
})
//Returns an array containing dominant [emotion_tone, language_tone, social_tone]
return renderData(max);
}
}
function renderData(max) {
console.log(max);
};
Maybe this is what you are intending? It will iterate through the entire data object calculating a max for each iteration, collect them in an array, and then finally call the renderData func with that array.
function calculateData(data) {
var maxes = [];
for (i in data) {
var arr = [];
var max;
var obj = data[i].tones;
obj.map(function(item) {
var data = item.score;
arr.push(data);
})
maxes.push(arr.reduce(function(a, b) {
return Math.max(a, b);
}));
}
return renderData(maxes);
}
function renderData(max) {
console.log(max);
};
I created a second array, finalArray and pushed each max into it:
function calculateData(data) {
var finalArr = [];
for (i in data) {
var arr = [];
var max;
data[i].tones.map(function(item) {
arr.push(item.score);
})
var max = arr.reduce(function(a, b) {
return Math.max(a, b);
});
finalArr.push(max);
//Returns an array containing dominant [emotion_tone, language_tone, social_tone]
// return renderData(max);
}
renderData(finalArr);
}
function renderData(finalArr) {
console.log(finalArr);
};
Thanks for your help guys!
Your error arises because the return statement inside the loop aborts the whole function, and therefore also the loop. But this whole function can be simplified/shortened quite a bit:
And as mentioned in the comments, don't define functions inside a loop (unless it is inevitable), define the before the loop. I did this in by defining the functions getScore and max in my code.
//ES6
function calculateData(data) {
var getScore = item => item.score,
max = (a,b) => Math.max(a,b),
maxima = Object.values(data)
.map(value => value.tones.map(getScore).reduce(max));
return renderData(maxima);
}
//Or maybe you're more comfortable without Arrow functions
function calculateData(data) {
function getScore(item){ return item.score }
function max(a,b){ return Math.max(a,b) }
var maxima = Object.values(data).map(function(value){
return value.tones.map(getScore).reduce(max)
});
return renderData(maxima);
}
The only difference to your code is that Object.values() returns only own values of the object, whereas for..in iterates over all values of the object, own and inherited.

javascript iterate through and map a multi-dimensional array

I want to apply a function to each of the values at all levels of the array:
arr = [[1,2,3],[1,2,3],[[1,2],[1,2]],1,2,3]
for example, multiply all the values by 3, and map it in the same format as before so I get:
arr = [[3,6,9],[3,6,9],[[3,6],[3,6]],3,6,9]
What would be the best way to go about this?
I tried to use a recursive function:
function mapall(array){
array.map(function(obj){
if (Array.isArray(obj)===true) { return mapall(obj) }
else{ return obj*3 }
})
};
but when I run it I just get undefined, so I must be doing something not quite right??
Any ideas??
Thanks
Everything was working, but you forgot to return from array.map. Here's a cleaner version of your code:
var arr = [[1,2,3],[1,2,3],[[1,2],[1,2]],1,2,3];
function mapAll(array){
return array.map(function(item){
return Array.isArray(item) ? mapAll(item) : item * 3;
});
}
alert(JSON.stringify(mapAll(arr)));
Version with callback function where you can do with array elements what you want (el * 2 or something else)
var arr = [[1,2,3],[1,2,3],[[1,2],[1,2]],1,2,3];
function mapAll(array, cb) {
for (var i = 0, len = array.length; i < len; i++) {
if (Array.isArray(array[i])) {
mapAll(array[i], cb);
} else {
array[i] = cb(array[i]);
}
}
return array;
};
var res = mapAll(arr, function (el) {
return el * 3;
});
console.log(JSON.stringify(res));

What is the best way to sum arrays using ECMASCRIPT 6 Generator/Functions

Is there a better way instead of adding values of arrays up using a generator function as closure?
var sumArrays = function(){
var sum = 0;
return function*(){
while(true){
var array = yield sum;
if(array.__proto__.constructor === Array){
sum += array.reduce(function(val,val2){ return val+val2; });
}
else sum=0;
}
};
};
var gen = sumArrays();
// is this step required to make a generator or could it be done at least differently to spare yourself from doing this step?
gen = gen();
// sum some values of arrays up
console.log('sum: ',gen.next()); // Object { value=0, done=false}
console.log('sum: ',gen.next([1,2,3,4])); // Object { value=10, done=false}
console.log('sum: ',gen.next([6,7])); // Object { value=23, done=false}
// reset values
console.log('sum: ',gen.next(false)); // Object { value=0, done=false}
console.log('sum: ',gen.next([5])); // Object { value=5, done=false}
This doesn't seem to be a problem generators are supposed to solve, so I would not use a generator here.
Directly using reduce (ES5) seems to be more appropriate:
let sum = [1,2,3,4].reduce((sum, x) => sum + x);
As a function:
function sum(arr) {
return arr.reduce((sum, x) => sum + x);
}
If you really want to sum multiple arrays across multiple function calls, then return a normal function:
function getArraySummation() {
let total = 0;
let reducer = (sum, x) => sum + x;
return arr => total + arr.reduce(reducer);
}
let sum = getArraySummation();
console.log('sum:', sum([1,2,3])); // sum: 6
console.log('sum:', sum([4,5,6])); // sum: 15
Keep it simple.
Here is use of for/of loop and arrow function,
const sumArray = myArray => {
let sum = 0;
for(const value of myArray)
sum+= value;
return sum;
}
const myArray = [1, 2, 5];
console.log(sumArray(myArray));

fastest way to detect if duplicate entry exists in javascript array?

var arr = ['test0','test2','test0'];
Like the above,there are two identical entries with value "test0",how to check it most efficiently?
If you sort the array, the duplicates are next to each other so that they are easy to find:
arr.sort();
var last = arr[0];
for (var i=1; i<arr.length; i++) {
if (arr[i] == last) alert('Duplicate : '+last);
last = arr[i];
}
This will do the job on any array and is probably about as optimized as possible for handling the general case (finding a duplicate in any possible array). For more specific cases (e.g. arrays containing only strings) you could do better than this.
function hasDuplicate(arr) {
var i = arr.length, j, val;
while (i--) {
val = arr[i];
j = i;
while (j--) {
if (arr[j] === val) {
return true;
}
}
}
return false;
}
There are lots of answers here but not all of them "feel" nice... So I'll throw my hat in.
If you are using lodash:
function containsDuplicates(array) {
return _.uniq(array).length !== array.length;
}
If you can use ES6 Sets, it simply becomes:
function containsDuplicates(array) {
return array.length !== new Set(array).size
}
With vanilla javascript:
function containsDuplicates(array) {
return array
.sort()
.some(function (item, i, items) {
return item === items[i + 1]
})
}
However, sometimes you may want to check if the items are duplicated on a certain field.
This is how I'd handle that:
containsDuplicates([{country: 'AU'}, {country: 'UK'}, {country: 'AU'}], 'country')
function containsDuplicates(array, attribute) {
return array
.map(function (item) { return item[attribute] })
.sort()
.some(function (item, i, items) {
return item === items[i + 1]
})
}
Loop stops when found first duplicate:
function has_duplicates(arr) {
var x = {}, len = arr.length;
for (var i = 0; i < len; i++) {
if (x[arr[i]]) {
return true;
}
x[arr[i]] = true;
}
return false;
}
Edit (fix 'toString' issue):
function has_duplicates(arr) {
var x = {}, len = arr.length;
for (var i = 0; i < len; i++) {
if (x[arr[i]] === true) {
return true;
}
x[arr[i]] = true;
}
return false;
}
this will correct for case has_duplicates(['toString']); etc..
var index = myArray.indexOf(strElement);
if (index < 0) {
myArray.push(strElement);
console.log("Added Into Array" + strElement);
} else {
console.log("Already Exists at " + index);
}
You can convert the array to to a Set instance, then convert to an array and check if the length is same before and after the conversion.
const hasDuplicates = (array) => {
const arr = ['test0','test2','test0'];
const uniqueItems = new Set(array);
return array.length !== uniqueItems.size();
};
console.log(`Has duplicates : ${hasDuplicates(['test0','test2','test0'])}`);
console.log(`Has duplicates : ${hasDuplicates(['test0','test2','test3'])}`);
Sorting is O(n log n) and not O(n). Building a hash map is O(n). It costs more memory than an in-place sort but you asked for the "fastest." (I'm positive this can be optimized but it is optimal up to a constant factor.)
function hasDuplicate(arr) {
var hash = {};
var hasDuplicate = false;
arr.forEach(function(val) {
if (hash[val]) {
hasDuplicate = true;
return;
}
hash[val] = true;
});
return hasDuplicate;
}
It depends on the input array size. I've done some performance tests with Node.js performance hooks and found out that for really small arrays (1,000 to 10,000 entries) Set solution might be faster. But if your array is bigger (like 100,000 elements) plain Object (i. e. hash) solution becomes faster. Here's the code so you can try it out for yourself:
const { performance } = require('perf_hooks');
function objectSolution(nums) {
let testObj = {};
for (var i = 0; i < nums.length; i++) {
let aNum = nums[i];
if (testObj[aNum]) {
return true;
} else {
testObj[aNum] = true;
}
}
return false;
}
function setSolution(nums) {
let testSet = new Set(nums);
return testSet.size !== nums.length;
}
function sortSomeSolution(nums) {
return nums
.sort()
.some(function (item, i, items) {
return item === items[i + 1]
})
}
function runTest(testFunction, testArray) {
console.log(' Running test:', testFunction.name);
let start = performance.now();
let result = testFunction(testArray);
let end = performance.now();
console.log(' Duration:', end - start, 'ms');
}
let arr = [];
let setSize = 100000;
for (var i = 0; i < setSize; i++) {
arr.push(i);
}
console.log('Set size:', setSize);
runTest(objectSolution, arr);
runTest(setSolution, arr);
runTest(sortSomeSolution, arr);
On my Lenovo IdeaPad with i3-8130U Node.js v. 16.6.2 gives me following results for the array of 1,000:
results for the array of 100,000:
Assuming all you want is to detect how many duplicates of 'test0' are in the array. I guess an easy way to do that is to use the join method to transform the array in a string, and then use the match method.
var arr= ['test0','test2','test0'];
var str = arr.join();
console.log(str) //"test0,test2,test0"
var duplicates = str.match(/test0/g);
var duplicateNumber = duplicates.length;
console.log(duplicateNumber); //2

Categories

Resources