Make average of values inside array to smooth graph line - javascript

I have an array which represents the points of a graph with different values like the following one:
var array = [5, 3, 4, 1, 2];
I would like to loop through it and create a new array where the new values are:
An average between the value preceding it and the one coming after it.
Placed among the existing ones.
This means that array[0] will remain at the same position, while the other values will be pushed of one position. The new array should look like this:
var newArray = [5, 4, 3, 3.5, 4, 2.5, 1, 1.5, 2];
Do you have an idea on how to achieve this? Thanks in advance to your replies!

var array = [5, 3, 4, 1, 2];
var newArr = [array[0]]; // start the array with the first from the original
array.reduce((a, b) => {
newArr.push((a + b) / 2, b);
return b;
});
console.log(newArr);

var array = [5, 3, 4, 1, 2];
var newArray = [];
newArray.push(array[0]);
for(var i=0; i < array.length-1; i++)
{
var first = array[i];
var second = array[i+1];
var avg = (first+second)/2;
newArray.push(avg);
newArray.push(second);
}
https://jsfiddle.net/5utkvge8/

You are going to want to loop through your original array, pushing each number to the new one, and if you are not on the final element, get the average of array[i] and array[i+1]
var array = [5, 3, 4, 1, 2];
var newArray = [];
for (var i = 0; i < array.length; i++)
{
newArray.push(array[i])
if (!isNaN(array[i+1]))
{
newArray.push((array[i] + array[i+1]) / 2)
}
}

or in a functional, no-side effects, way:
var array = [5, 3, 4, 1, 2];
var newArray = array.reduce((result, value, index, array) => result.concat(index > 0 && index < array.length ? [(array[index-1] + value)/2, value] : value), [])

In case you can modify the original array:
var array = [5, 3, 4, 1, 2],
len = array.length * 2 - 2;
for (var i = 1; i < len; i = i + 2) {
array.splice(i, null, (array[i-1] + array[i]) / 2);
}
console.log(array);

let createdArr = []
[5, 3, 4, 1, 2].forEach( (item,index,arr) => {
createdArr.push(item)
if( index !== 0 && index + 1 !== arr.length ){
createdArr.push( (item + arr[ index + 1]) / 2 )
}
} )

Related

How to calculate the difference between of the elements in an array starting from the last up to the first in JavaScript?

This is an array given:
arrayNum = [1, 2, 4, 5, 8, 9];
arrayS = [];
for(var i=1, len = array1.length; i<len; i++){
arrayS.push(arrayNum[i]-arrayNum[i-1]);
}
console.log(arrayS);
This code calculates the difference between each two consecutive elements!
However I need to calculate the difference between elements starting from the last up to the first element what would be in this particular case 9-8-5-4-2-1 = -11?!
s1=0;
for(var j=array1[array1.length-1]; j>0; j--){
s1 = s1 - array1[j];
}
console.log(s1);
However this is not working!
In your original solution, you should iterate the index, rather than the element
const arrayNum = [1, 2, 4, 5, 8, 9];
s1 = arrayNum[arrayNum.length - 1];
for (var j = arrayNum.length - 2; j >= 0; j--) {
s1 = s1 - arrayNum[j];
}
console.log(s1);
Or you could use reduce
const arrayNum = [1, 2, 4, 5, 8, 9];
const res = arrayNum.reduce(
(acc, el, index) => acc + (index !== arrayNum.length - 1 ? -1 : 1) * el,
0
);
console.log(res);
You can use Array.reduceRight() to calculate the difference from the end of the array.
Note: that reduce/reduceRight would throw an error when reducing an empty array without an initial value. I use a ternary to check the length, and if it's empty return NaN.
const fn = arr =>
arr.length ?
arrayNum.reduceRight((s, n) => s - n) // if array is not empty
:
NaN // if array is empty
const arrayNum = [1, 2, 4, 5, 8, 9];
const result = arrayNum.reduceRight((s, n) => s - n)
console.log(result);
For the for loop to work, you need to initialize s1 without setting a value, and j with the last index. When calculating s1 check if it's undefined, and initialize it with the current number. If it's not, subtract the current number:
const array1 = [1, 2, 4, 5, 8, 9];
let s1;
for (let j = array1.length - 1; j >= 0; j--) {
s1 = s1 === undefined ? array1[j] : s1 - array1[j];
}
console.log(s1);
Expression 9-8-5-4-2-1 is equal to -(-9+8+5+4+2+1).
-9+8+5+4+2+1 is equal to (-(9*2) + (9+8+5+4+2+1)).
const arrayNum = [1, 2, 4, 5, 8, 9];
const res = -arrayNum.reduce((acc, num) => acc + num
, -arrayNum[arrayNum.length - 1] * 2)
console.log(res)
Issue is with var j=array1[array1.length-1];, not correct index to start with in for-loop.
Try the while loop, should simplify for this case.
array1 = [1, 2, 4, 5, 8, 9];
s1 = array1[array1.length-1];
j = array1.length-1;
while (--j >= 0) s1 -= array1[j];
console.log(s1);

odd to even numbers in an array javascript [duplicate]

This question already has answers here:
Loop through an array in JavaScript
(46 answers)
Closed 3 years ago.
In an array, it prints out all odd numbers to even numbers, not changing even numbers.
For example, [1, 2, 3, 4] => [2, 2, 6, 4]
var result = '';
var i = 0;
if(array[i]%2 === 1) {
result = array[i]*2;
}
This code prints out only odd number, excluding even numbers in an array.
For example, [1, 2, 3] => [2]
Based on the given example:
[1, 2, 3, 4] => [2, 2, 6, 4]
I take it that every odd number has to be doubled.
Based on that assumption, here is the code:
for (let i = 0; i < array.length; i++)
if (array[i] % 2 !== 0)
array[i] *= 2;
console.log(array);
try this:
var arr = [1, 2, 3, 4]
for (var i = 0; i < arr.length; i++) {
if(arr[i]%2 != 0) {
arr[i] = arr[i]*2;
}
}
console.log(arr);
You need to push even numbers as well.
var array = [1, 2, 3, 4],
result = [],
i = 0;
for (i = 0; i < array.length; i++) {
if (array[i] % 2 === 1) {
result.push(array[i] * 2);
} else {
result.push(array[i]);
}
}
console.log(result);
A shorter approach
var array = [1, 2, 3, 4],
result = array.map(v => v % 2 ? 2 * v : v);
console.log(result);
you can use bitwise & also to check even or odd, lil faster if you have large arrays.
let out = [1, 2, 3, 4].map(e => e & 1 ? e * 2 : e);
console.log(out)
In the loop, check if the item is odd (% returns something other than 0). If it's odd push it's double, if not push the original number:
var array = [1, 2, 3, 4]
var result = []
for(var i = 0; i < array.length; i++) {
result.push(array[i] % 2 ? array[i] * 2 : array[i])
}
console.log(result)
You can also use Array.map():
const array = [1, 2, 3, 4]
const result = array.map(n => n * (n % 2 + 1))
console.log(result)
var array = [1, 2, 3, 4]
var result = [];
var i = 0;
for (var j = 0; j < array.length; j++) {
if(array[j]%2 === 1) {
result.push(array[j]*2);
} else {
result.push(array[j])
}
}
console.log(result)

Array truncation with splice method

I need to delete occurrences of an element if it occurs more than n times.
For example, there is this array:
[20,37,20,21]
And the output should be:
[20,37,21]
I thought one way of solving this could be with the splice method
First I sort the array it order to make it like this:
[20,20,37,21]
Then I check if the current element is not equal to the next and split the array into chunks, so it should look like:
[20, 20],[37],[21]
Later I can edit the chunk longer than 1 and join it all again.
This is what the code looks like in my head but didn't work in real life
var array = [20, 37, 20, 21];
var chunk = [];
for(i = 0; i < array.length; i++) {
if(array[i] !== array[i + 1]) {
var index = array.indexOf(array[i]);
chunk.push = array.splice(0, index) // cut from zero to last duplicate element
} else
var index2 = a.indexOf(a[i]);
chunk.push(a.splice(0, index));
}
with this code the output is
[[], [20, 20]]
I think It's something in the 'else' but can't figure it out what to fix.
As the logic you want to achieve is to delete n occurrences of element in an array, your code could be as follow:
var array = [1, 1, 3, 3, 7, 2, 2, 2, 2];
var n = 2;
var removeMultipleOccurences = function(array, n) {
var filteredArray = [];
var counts = {};
for(var i = 0; i < array.length; i++) {
var x = array[i];
counts[x] = counts[x] ? counts[x] + 1 : 1;
if (counts[x] <= n) filteredArray.push(array[i])
}
return filteredArray;
}
console.log(removeMultipleOccurences(array, n));
I came up with this one, based on array filter checking repeated values up to a limit, but I can see #Basim's function does the same.
function removeDuplicatesAbove(arr, max) {
if (max > arr.length) {max = arr.length;}
if (!max) {return arr;}
return arr.filter(function (v, i) {
var under = true, base = -1;
for (var n = 0; n < max; n++) {
base = arr.indexOf(v, base+1); if (base == -1) {break;}
}
if (base != -1 && base < i) {under = false;}
return under;
});
}
var exampleArray = [20, 37, 20, 20, 20, 37, 22, 37, 20, 21, 37];
console.log(removeDuplicatesAbove(exampleArray, 3)); // [20, 37, 20, 20, 37, 22, 37, 21]
Always when you use splice() you truncate the array. Truncate the array with the length of same values from the start with the help of lastIndexOf(). It always starts from 0.
[ 1, 1, 1, 2, 2, 2, 3, 4, 4, 5 ] // splice(0, 3)
[ 2, 2, 2, 3, 4, 4, 5 ] // splice(0, 3)
[ 3, 4, 4, 5 ] // splice(0, 1)
[ 4, 4, 5 ] // splice(0, 2)
[ 5 ] // splice(0, 1)
Do this as long as the array length is greater than 0.
var arr = [1, 1, 1, 2, 2, 2, 3, 4, 4, 5];
var res = [];
while (arr.length > 0) {
var n = arr[0];
var last = arr.lastIndexOf(n) + 1;
res.push(n);
arr.splice(0, last);
}
console.log(res);
You can use Array.prototype.reduce(), Array.prototype.filter() to check if n previous elements are the same as current element
let cull = (arr, n) => arr.reduce((res, curr) => [...res
, res.filter(v => v === curr).length === n
? !1 : curr].filter(Boolean), []);
let arrays = [[20,37,20,21], [1,1,3,3,7,2,2,2,2]];
let cullone = cull(arrays[0], 1);
let cullthree = cull(arrays[1], 3);
console.log(cullone // [20, 37, 21]
, cullthree // [1, 1, 3, 3, 7, 2, 2, 2]
);

How to sort an array sequencial in javascript?

I'm not sure if the title of this question is correct or not and also not sure what the appropriate keyword to search on google.
I have an array look like:
var myArray = [1,1,2,2,2,3,4,4,4];
and I want to sort my array into:
var myArray = [1,2,3,4,1,2,4,2,4];
Please in to my expected result. the order is ascending but duplicate value will repeated on last sequence instead of put it together in adjacent keys. So the expected result grouped as 1,2,3,4 1,2,4 and 2,4.
Thank you for your help and sorry for my bad English.
This code works. But it may exist a better solution.
// We assume myArray is already sorted
var myArray = [1,1,2,2,2,3,4,4,4],
result = [];
while (myArray.length) {
var value = myArray.shift();
// Find place
var index = 0;
while(result[index] && result[index][result[index].length - 1] == value) index++;
if(!result[index]) {
result[index] = [];
}
result[index][result[index].length] = value;
}
result.reduce(function(current, sum) {
return current.concat(sum);
});
console.log(result) // Display [1, 2, 3, 4, 1, 2, 4, 2, 4]
Here is my method using JQuery and it does not assume the array is already sorted.
It will iterate through the array and no duplicates to tempResultArray, once finished, it will then add them to the existing result and repeat the process again to find duplicates.
This is not the most efficient method, but it can be handled by one function and does not require the array to be sorted.
var myArray = [1,1,2,2,2,3,4,4,4],result = [];
while (myArray && myArray.length) {
myArray = customSort(myArray);
}
console.log(result);
function customSort(myArray){
var tempResultArray = [], tempMyArray = [];
$.each(myArray, function(i, el){
if($.inArray(el, tempResultArray ) === -1){
tempResultArray.push(el);
}else{
tempMyArray.push(el);
}
});
tempResultArray.sort(function(a, b){return a-b});
$.merge( result,tempResultArray)
return tempMyArray;
}
JSFiddle
This proposal features a straight forward approach with focus on array methods.
function sprout(array) {
return array.reduce(function (r, a) {
!r.some(function (b) {
if (b[b.length - 1] < a) {
b.push(a);
return true;
}
}) && r.push([a]);
return r;
}, []).reduce(function (r, a) {
return r.concat(a);
});
}
document.write('<pre>' + JSON.stringify(sprout([1, 1, 2, 2, 2, 3, 4, 4, 4]), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(sprout([1, 2, 3, 7, 7, 7]), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(sprout([1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 6, 7]), 0, 4) + '</pre>');
here's another solution:
var myArray = [1, 1, 2, 2, 2, 3, 4, 4, 4];
function mySequelArray(arr) {
var res = arguments[1] || [];
var nextVal;
var min = Math.min.apply(null, arr);
if (res.length > 0) {
nextVal = arr.filter(function (x) {
return x > res[res.length - 1]
}).sort()[0] || min;
} else {
nextVal = min;
}
res.push(nextVal);
arr.splice(arr.indexOf(nextVal), 1);
return (arr.length > 0) ? mySequelArray(arr, res) : res;
}
console.log(mySequelArray(myArray))
fiddle
My best approach will be to split your array into separate arrays for each repeated value, then arrange each separate array and join altogether.
UPDATED:
I wrote a quick code sample that should work if the same number in inputArray is not given more than twice. You could improve it by making it recursive thus creating new arrays for each new number and removing the limitation. Had some free time so i re-wrote a recursive function to sort any given array in sequence groups like you wanted. Works like a charm, inputArray does not need to be sorted and doesn't require any libraries. Jsfiddle here.
var inputArray = [3, 4, 1, 2, 3, 1, 2, 4, 1, 2, 5, 1];
var result = sortInSequence(inputArray);
console.log(result); //output: [1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2, 1]
function sortInSequence(inputArray){
var inputArraySize = inputArray.length,
tempArray = [], //holds new array we are populating
sameValuesArray = [], //holds same values that we will pass as param in recursive call
rSorted = []; //init sorted array in case we have no same values
for(var i = inputArraySize; i > 0; i--){
var value = inputArray.pop();
tempArray.push(value);
var counter = 0,
tempArraySize = tempArray.length;
for(var j = 0; j < tempArraySize; j++){
if(tempArray[j] == value){
counter++;
}
}
if(counter == 2){
//value found twice, so remove it from tempArray and add it in sameValuesArray
var sameValue = tempArray.pop();
sameValuesArray.push(sameValue);
}
}
if(sameValuesArray.length > 0){
rSorted = sortInSequence(sameValuesArray);
}
tempArray.sort();
return tempArray.concat(rSorted);
}

Java Script - Adding null value to array, if the element is not present at particular index

Array length is 7
Original array
var arr = [2, 4, 6];
Needed array
arr = [null,null,2,null,4,null,6];
0 is not present in array so need to replace with null,
1 is not available replace with null and
2 is available so put 2 in new array so on..
You can use the splice() method on the array
var arr=[2,4,6];
var l = arr[arr.length-1];
for(var i=0; i<=l; i++){
if(arr[i] !== i){
arr.splice(i, 0, null);
}
}
Output : [null, null, 2, null, 4, null, 6]
This modifies the original array.
I will write a permanence case for all answers soon.
function createArrayFromArray(array, length) {
var new_array = new Array(length);
for (var i = 0; i < new_array.length; i++) {
new_array[i] = null;
}
for (var i = 0; i < array.length; i++) {
new_array[array[i]] = array[i];
}
return new_array;
}
console.log(createArrayFromArray(arr, 7)); //[null, null, 2, null, 4, null, 6]
You just need to find the max value in the array and then iterate from 0 to that max, checking each value to see if it was present in the source or not:
var arr = [2, 4, 6];
var max = Math.max.apply(Math, arr);
var result = [];
for (var i = 0; i <= max; i++) {
if (arr.indexOf(i) !== -1) {
result[i] = i;
} else {
result[i] = null;
}
}
Working demo: http://jsfiddle.net/jfriend00/c7p8mkqy/
As I asked in my comments, I'd like to know what problem you're actually trying to solve because it seems like both the original and the newly created data structures are inefficient structures that could probably use different form of data and work more efficiently. But, we can only help you make a wiser choice if you explain the actual problem, rather just your attempted solution.
Given you have the only input arr which you want to fill null inside. Try this:
var arr = [2, 4, 6];
var output = [];
while (arr.length>0){
var first = arr.splice(0,1);
while (output.length<first[0])
output.push(null);
output.push(first[0]);
}
// output should be [null,null,2,null,4,null,6];
Try:
var arr = [2, 4, 6];
var new_arr = [];
var i = 0;
while(i < 7){
var pos = arr.indexOf(i++);
new_arr.push(pos !== -1 ? arr[pos] : null)
}
document.write(JSON.stringify(new_arr, null, 4))
var arr = [2, 4, 6];
var result = new Array(7);
arr.forEach(function(a) { result[a] = a;});
Interesting quiz:
var arr = [2, 4, 6]
var n = 0
while(arr.length > n) {
if(arr[n] !== n) {
arr = arr.slice(0,n).concat(null, arr.slice(n))
}
n++
}
console.log(arr) // [null, null, 2, null, 4, null, 6]
This approach applies to array consists of random number of sorted integers.
var arr = [2, 4, 6];
var narr = (new Array(arr.sort()[arr.length-1]))
arr.map(function(v){
narr[v] = v;
});
for (var i = 0; i<narr.length; i++) narr[i]||(narr[i]=null);
console.log(narr);
Try splice():
var arr = [2, 4, 6];
var i = 0,
l = arr[arr.length - 1];
while (i < l) {
if(i !== arr[i])
arr.splice(i, 0, null);
i++;
}
console.log(arr); //[ null, null, 2, null, 4, null, 6 ]

Categories