Related
A task:
Write a function that takes an array and a number n. Then output an array in which there are no elements that are repeated more than n times.
Example:
Input:
n = 3;
arr = [1, 2, 4, 4, 4, 2, 2, 2, 2]
Output:
result = [1, 2, 4, 4, 4, 2, 2]
Tried to do something like that, but it's not working correctly.
let arr = [1, 2, 4, 4, 4, 2, 2, 2, 2];
let new_set = [...new Set(arr)];
let result = [];
console.log(new_set); // [1, 2, 4]
first:
for (let i = 0; i < arr.length; i++) {
if (arr[i] === arr[i - 1]) {
continue first;
}
else {
let count = 0;
for (let j = i; j < arr.length; j++) {
if ((arr[i] === arr[j]) && (count < 3)) {
result.push(arr[j]);
}
}
}
}
You need a persistent outer variable that keeps track of how many times an item has been iterated over so far. Once past the limit, don't push the item being iterated over to the result.
const arr = [1, 2, 4, 4, 4, 2, 2, 2, 2]
let n = 3;
const counts = {};
const result = [];
for (const item of arr) {
counts[item] = (counts[item] || 0) + 1;
if (counts[item] <= n) {
result.push(item);
}
}
console.log(result);
Another option, if you want to use Array.reduce.
It's not as optimised as #CertainPerformance as it uses a filter inside a loop. But for small arrays like this unlikely to make much difference.
const arr = [1, 2, 4, 4, 4, 2, 2, 2, 2]
let n = 3;
const result = arr.reduce((a,v)=>(
a.filter(f=>f===v).length < n ?a.push(v):a,a),[]);
console.log(result);
Code golf version using reduce and without array.filter:
const f=(n,a)=>a.reduce((({c={},r=[]},i)=>
(c[i]??=0,++c[i]>n?0:r.push(i),{c,r})),{}).r;
console.log(f(3, [1, 2, 4, 4, 4, 2, 2, 2, 2]).join());
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);
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 )
}
} )
What is an efficient way of looping through two arrays to produce an alternating output? In JavaScript.
If I have two arrays like this:
var oddNumbers = [1, 3, 5, 7, 9]
var evenNumbers = [2, 4, 6, 8, 10, 12, 14]
NB: The arrays may not be the same length
How can I get the following output?
Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14
I would have thought this would work:
if (oddNumber.length > evenNumbers.length) {
var large = oddNumbers;
} else {
var large = evenNumbers;
}
for(var i = 0; i < large.length; i++){
if (evenNumbers.length >= i && oddNumbers.length >= i) {
console.log(oddNumbers[i] + ", " + evenNumbers[0]);
} elseif (evenNumbers.length >= i) {
console.log(evenNumbers[0]);
} else {
console.log(oddNumbers[0]);
}
}
But it's pretty messy, any better way of approaching this?
NOTE: These may not necessarily be in a numerical order, or in fact numbers
I would rather do it as follows if you just want to output them:
var oddNumbers = [1, 3, 5, 7, 9];
var evenNumbers = [2, 4, 6, 8, 10, 12, 14];
for (var i=0, j=0; i < oddNumbers.length || j < evenNumbers.length;) {
if (i < oddNumbers.length) {
console.log(oddNumbers[i++]);
}
if (j < evenNumbers.length) {
console.log(evenNumbers[j++]);
}
}
If you want to get the merge result as another array you can replace console.log with result.push to push result values on an array named result as follows:
var oddNumbers = [1, 3, 5, 7, 9];
var evenNumbers = [2, 4, 6, 8, 10, 12, 14];
var result = [];
for (var i=0, j=0; i < oddNumbers.length || j < evenNumbers.length;) {
if (i < oddNumbers.length) {
result.push(oddNumbers[i++]);
}
if (j < evenNumbers.length) {
result.push(evenNumbers[j++]);
}
}
console.log(result);
This way you iterate both arrays as long as one of them has an element that we haven't visited yet and also prevents iterating over the same index of same array twice. Please note that I used increment in if blocks to save 2 lines of code. You can also move them to the for loop since they won't break if statements.
var oddNumbers = [1, 3, 5, 7, 9];
var evenNumbers = [2, 4, 6, 8, 10, 12, 14];
var oLength = oddNumbers.length;
var eLength = evenNumbers.length;
var n = oLength > eLength ? oLength : eLength;
var rez=[];
for(i=0;i<n;i++){
if (i< oLength) rez.push(oddNumbers[i])
if (i<eLength) rez.push(evenNumbers[i])
}
console.log(rez);
var odd = ["A", "C","E","G"];
var even = ["B","D","F"];
var rez=[];
for(i=0;i<(odd.length > even.length ? odd.length : even.length);i++){
if (i< odd.length) rez.push(odd[i])
if (i<even.length) rez.push(even[i])
}
console.log(rez);
The following function accepts two arrays and returns their interleaved values as a new array:
function interleaveArrays(a, b) {
var array = [],
limit = a.length >= b.length ? a.length : b.length;
index = 0;
while (index < limit) {
a[index] && array.push(a[index]);
b[index] && array.push(b[index]);
index += 1;
}
return array;
}
Calling the function like so:
var oddNumbers = [1, 3, 5, 7, 9],
evenNumbers = [2, 4, 6, 8, 10, 12, 14];
console.log(interleaveArrays(oddNumbers, evenNumbers));
Yields:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14 ]
You can then output this in your preferred manner; e.g:
var interleaved = interleaveArrays(oddNumbers, evenNumbers);
// as a loop
interleaved.forEach(function (n) {
console.log(n);
})
// or as a string
console.log(interleaved.join(', '));
// etc.
Hope this helps :)
I'd do something like this.
large = (oddNumber.length >= evenNumbers.length) ? oddNumbers : evenNumbers;
small = (oddNumber.length < evenNumbers.length) ? oddNumbers : evenNumbers;
for(var i = 0; i < large.length; i++){
if(small.length <= i + 1){
console.log(small[i] + ", "+ large[i]);
}
else {
console.log(large[i]);
}
}
A long-hand example of how it can be done. The code can be shrunk for a final solution. The basic principle I'm using is to even out the lengths to take care of the alternating then tag on the tail
var oddNumbers = [1, 3, 5, 7, 9];
var evenNumbers = [2, 4, 6, 8, 10, 12, 14];
var oLength = oddNumbers.length;
var eLength = evenNumbers.length;
var oTemp, eTemp, remainder;
if(oLength > eLength) {
eTemp = evenNumbers;
oTemp = oddNumbers.slice(0, eLength);
remainder = oddNumbers.slice(eLength);
} else if (eLength > oLength) {
eTemp = evenNumbers.slice(0, oLength);
oTemp = oddNumbers;
remainder = evenNumbers.slice(oLength);
} else {
eTemp = evenNumbers;
oTemp = oddNumbers;
remainder = [];
}
var final = [];
for(var i=0; i < eTemp.length; i++) {
final.push(oTemp[i]);
final.push(eTemp[i]);
}
final = final.concat(remainder);
alert(final);
I would simply merge the two array and sort it
var oddNumbers = [1, 3, 5, 7, 9];
var evenNumbers = [2, 4, 6, 8, 10, 12, 14];
var mergedArr=oddNumbers.concat(evenNumbers );
console.log(mergedArr.sort(function(a,b){return a-b;}));
See No loop.. No hassle. Very Simple
There will be an extra , on the screen. Add an if statement if you don't want that
for(var i = 0; i < large.length; i++){
if(i<evenNumbers.length)
console.log(evenNumbers[i]+",");
if(i<oddNumber.length)
console.log(evenNumbers[i]+",");
}
try this it will work always either number Array or String Array:
var oddNumber = [1, 3, 5, 7, 9]
var evenNumber = [2, 4, 6, 8, 10, 12, 14]
var margedNumbers = oddNumber.concat(evenNumber);
console.log("before: "+margedNumbers);
margedNumbers.sort(function(a, b){return a-b})
console.log("after: "+margedNumbers)
My solution
var oddNumbers = [1, 3, 5, 7, 9]
var evenNumbers = [2, 4, 6, 8, 10, 12, 14]
var extraElements = (oddNumbers.length > evenNumbers.length) ? oddNumbers.slice(evenNumbers.length) : evenNumbers.slice(oddNumbers.length);
var finalArr = [];
var small = (oddNumbers.length < evenNumbers.length) ? oddNumbers : evenNumbers;
small.forEach((each, index) => {
// merge elements in desired order
finalArr.push(oddNumbers[index]);
finalArr.push(evenNumbers[index]);
})
finalArr = finalArr.concat(extraElements);
alert(finalArr);
Extract the extra elements which makes both array of same length. Then, in a simple iteration, push elements from both array with same index.
here is my problem: I have 5 arrays of integer like these in javascript:
array1 = [0, 1, 2, 3, 4];
array2 = [9, 1, 2, 3, 4];
array3 = [10, 1, 2, 11, 4];
array4 = [12, 1, 2, 13, 4];
array5 = [14, 1, 2, 15, 4];
I have to find the longest common subarray. In this case I have to retrieve the following subarray: [1, 2, 4].
For the records, I won't find repetitions inside arrays and my main goal is not execution speed.
thanks
here is the solution using Set in Javascript
var myArray = [array1 , array2 ,array3 , array4 ,array5];
let keys = new Set();
myArray.forEach(arr => arr.forEach(el => keys.add(el) ))
var common = [...keys].filter(key => myArray.every(arr => arr.includes(key)))
console.log(common);
#define MAX(a,b) a>b?a:b
int main(int argc, char* argv[])
{
if(argc < 2)
return -1;
int x = strlen(argv[1])+1;
int y = strlen(argv[2])+1;
int i,j,k,l;
int longest =0;
char* LCS = (char*)malloc(sizeof(char)*MAX(x,y));
int** arr = (int**)malloc(sizeof(int*)*x);
for(i=0;i<=y;i++)
arr[i] =(int*) malloc(sizeof(int)*y);
for(i=0;i<=x;i++)
for(j=0;j<=y;j++)
{
arr[i][j] = 0;
}
for(i=0;i<x;i++)
for(j=0;j<y;j++)
{
if(argv[1][i] == argv[2][j])
arr[i+1][j+1] = arr[i][j]+1;
if(arr[i+1][j+1] > longest)
{
longest =arr[i+1][j+1];
memset(LCS,0,MAX(x,y));
for( k=0,l=i;k<=longest;k++,l--)
LCS[k] = argv[1][l];
}
}
printf(" %s",argv[2]);
for(i=0;i<x;i++)
{
printf("\n%c",argv[1][i]);
for(j=0;j<y;j++)
{
printf("%d",arr[i][j]);
}
}
printf("\nLongest Common Subarray : %s\n",LCS);
return 0;
}
Try this:
var array1 = [0, 1, 2, 3, 4];
var array2 = [9, 1, 2, 3, 4];
var array3 = [10, 1, 2, 11, 4];
var array4 = [12, 1, 2, 13, 4];
var array5 = [14, 1, 2, 15, 4];
// join everything into one array
var all = array1.join(',')+','+array2.join(',')+','+array3.join(',')+','+array4.join(',')+','+array5.join(',');
all = all.split(',');
// get an object with all unique numbers as keys
var keys = {};
for(var i=0; i<all.length; i++) keys[all[i]] = 1;
console.log(keys);
// generate an array with values present in all arrays
var common = [];
for(var x in keys) {
if(array1.indexOf(parseInt(x)) != -1 && array2.indexOf(parseInt(x)) != -1 && array3.indexOf(parseInt(x)) != -1 && array4.indexOf(parseInt(x)) != -1 && array5.indexOf(parseInt(x)) != -1) {
common.push(x);
}
}
console.log(common);
I guess this can give you a good start:
My script will return you an object with the count of each elements. But for now, it takes the first array as base.
var array1 = [0, 1, 2, 3, 4];
var array2 = [9, 1, 2, 3, 4];
var array3 = [10, 1, 2, 11, 4];
var array4 = [12, 1, 2, 13, 4];
var array5 = [14, 1, 2, 15, 4];
var array6 = [13, 1, 2, 18, 4];
var mainArr = [array1, array2, array3, array4, array5, array6]
function getCommonElement(arr){
var subLength = arr[0].length;
var resultArr = new Array();
var ret = new Object();
for(var k=0;k<subLength;k++){
var temp = new Array();
for(var i=0;i<arr.length;i++){
temp.push(arr[i][k]);
}
resultArr.push(temp);
}
for(var i=0;i<arr[0].length;i++){
ret[arr[0][i]+''] = resultArr[i].join('').split(arr[0][i]+'').length - 1;
}
return ret;
}
Cheers.
/**
longest common subarray b/w 2 arrays
a = [2,3,4,5,6,7,8], b = [6,7,8,4,5,2,3]
ans = 6,7,8
basically create a 2d arr and if elements match dp[i][j] = 1 + dp[i-1][j-1];
if dp[i][j] > maxLen, update maxLen and store the index
Now that we have the maxLen, subarray will be from (index - maxLen) till index.
*/
int[] finMaxCommon(int[] a, int[] b){
int m = a.length, n = b.length, maxLen = 0;
int[][] dp = new int[m+1][n+1];
// i want a 0th row why? m->out of bounds; comparing i-1; i->1 then i-1 will be 0
for (int i = 1; i<=m; i++){
for(int j = 1; j<=n; j++){
if(a[i-1] == b[j-1]) {
dp[i][j] = 1 + dp[i-1][j-1];
maxLen = Math.max(maxLen, dp[i][j]);
}
}
}
// endIndex = 6, 3, a[6-3+1], a[6]
return new int[]{a[endIndex-maxLen+1], [endIndex]};
}
dry run
0,6,7,8,4,5,2,3
0, 0 //
2, 1 // (2,2) i = 1, j = 6 1 + dp[0][5]
3, 2 // (3,3) i = 2, j = 7 1 + dp[1][6]
4,
5,
6, 1
7, 2
8, 3