I have an unordered list like this;
list1 = [2,3,1,2,1,3,3,1,2]
I want to add +10 to the recurring elements in this list every time. So there should be a list as follows;
list1 = [2,3,1,12,11,13,23,21,22]
At the same time, the list order must remain intact.
In fact, the list is longer than the example here (10 digits repeat 7 times).
I would be grateful for your suggestions.
Just have a lookup which count the frequency of number and then multiply the frequency with 10 and add the number.
const list1 = [2,3,1,2,1,3,3,1,2],
lookup = {},
result = list1.map(number => {
lookup[number] = (lookup[number] || 0) + 1;
return number + (lookup[number] - 1) * 10;
});
console.log(result);
You can do it like this:
var list1 = [2,3,1,2,1,3,3,1,2];
var countObject = {};
list1.forEach(function(item, index) {
if(countObject[item]) {
list1[index] = item + (10 * countObject[item]);
countObject[item] = countObject[item] + 1;
} else {
countObject[item] = 1;
}
});
For a compact version, you could take a closure over an object for counting and assign zero to unknown property and increment this value.
const
list = [2, 3, 1, 2, 1, 3, 3, 1, 2],
result = list.map((o => v => v + 10 * (o[v] ??= 0, o[v]++))({}));
console.log(...result);
Related
Please bear with me this is difficult to explain. I will first explain how to do it successfully with only one set of data.
First, say I have an array like so yValuesMinusMean = [-5, -4, -1, 10]
I have another array like so xValuesMinusMean = [ 2.75,3.75,6.75,5.75 ]
Both of the above arrays can have numerous values. However, the length of both arrays is the same. So if the first one has 4, then the second one will definitely have 4.
I want to calculate the sum and product of the arrays. This is what I mean:
var sumOfXTimesYValues = this.calculateProductAndSum(yValuesMinusMean, xValuesMinusMean);
calculateProductAndSum(yValuesMinusMean = [], xValuesMinusMean = []) {
let total = 0;
for(let i = 0; i < yValuesMinusMean.length; i++) {
let product = (yValuesMinusMean[i] * xValuesMinusMean[i]);
total += product;
};
return total;
},
The result of this: console.log('sumOfXTimesYValues', sumOfXTimesYValues); is
17
LOGIC : (-5 * 2.75) + (-4 * 3.75) + (-1 * 6.75) + (10 * 5.25) = 17
So far, everything works. However, I want to make it so that instead of xValuesMinusMean being a single array with multiple numerical values, it will be a single array containing multiple arrays, with each array having the same number of elements as in yValuesMinusMean. Like so:
xValuesMinusMean = [ [ 2.75,3.75,6.75,5.75 ], [-2,-1,2,1]. .... ]
END GOAL: sumOfXTimesYValues = [17, 22, ...]
Logic for the second array item: (-5 * -2) + (-4 * -1) + (-1 * 2) + (10 * 1) = 22
Essentially, you're multiplying each value in each array in xValuesMinusMean with a value in yValuesMinusMean in the same order. So, -5 is the 0th item in the yValuesMinusMean array, and -2 is the 0th item in the array within xValuesMinusMean. So -5 * -2.
My next steps would be to do something like this:
xValuesMinusMean.forEach(element => {
for(let i = 0; i < xValuesMinusMean.length; i++) {
let product = (newCategoryArray[i] * xValuesMinusMean[i]);
total += product;
};
});
However, it yields the following: sumOfXTimesYValues = 352, which isn't correct. How would I be able to achieve the end goal?
END GOAL: sumOfXTimesYValues = [17, 22, ...]
Create a generic function for computing a scalar product (you've already got it):
function scalarProduct(a, b) {
let res = 0;
for(let i = 0; i < a.length; i++) {
res += a[i] * b[i];
}
return res;
}
and then map it over your matrix (array of vectors):
result = xValuesMinusMean.map(vec => scalarProduct(vec, yValuesMinusMean))
You can have one reduce function where you will take product of arrays and store it in accumulator.
const val =[ [ 2.75,3.75,6.75,5.25 ], [-2,-1,2,1]];
const yvalues = [-5, -4, -1, 10];
console.log(val.map(o=>o.reduce((a,e,i)=>a+=e*yvalues[i],0)));
Looks like your calculation is not correct first set of arrays will also return 22.
Live Demo :
const yValuesMinusMean = [-5, -4, -1, 10];
const xValuesMinusMean = [[2.75, 3.75, 6.75, 5.75], [-2, -1, 2, 1]];
const finalArr = [];
xValuesMinusMean.forEach(arr => {
let cal = 0;
arr.forEach((item, index) => {
cal += item * yValuesMinusMean[index]
});
finalArr.push(cal);
});
console.log(finalArr); // [22, 22]
I have a huge array of data that I got from PDF files. The pdfs had 10 data items per page but because it was presented in two columns the data is shuffled. The first and last item of each group of ten items are in the correct position but the rest are not.
The order is now 0,2,4,6,8,1,3,5,7,9,10,12,14,16,18,11...
and i need it to be 0,1,2,3...
I've tried looping through the array and pushing items to a new array using different if statements but just cant get it right.
Here is a function that takes the data as you get it, and two more arguments to indicate the number of columns and number of rows on a page:
function uncolumnize(data, numColumns, numRows) {
let perPage = numColumns * numRows;
return data.map((_, i) =>
data[Math.floor(i / perPage) * perPage
+ Math.floor((i % perPage) / numColumns)
+ (i % numColumns) * numRows]
);
}
let res = uncolumnize([0,2,4,6,8,1,3,5,7,9,10,12,14,16,18,11,13,15,17,19], 2, 5);
console.log(res);
It uses the map Array method, since the result (obviously) has just as many elements as the original data. The callback given to map does not use the value, but only the index. That index is used to determine the page, the row and the column. The latter two are reversed to rebuild a new index, and the data at that new index is returned.
2 columns of 10 elements per page will have groups of 10 as 10n,10n+2,10n+4,10n+6,10n+8,10n+1,10n+3,10n+5,10n+7,10n+9
There will be groups of 10 elements and one group (the last one) which will have 0-9 elements.
N = 5 //numbers of rows
len = numbers.length //numbers is the array
groups_of_2n_len = len/(2*N)
last_group_len = len%(2*N)
//For each group complete group
for(group_i = 0; group_i<groups_of_2n_len ; group_i=group_i +1)
{
//Store those 2N elements in an array
temp_array = numbers.slice(group_i*2*N,group_i*2*N + 2*N)
element = group_i*2*N
//Iterate row wise and fix the numbers
for(temp_i = 0; temp_i< N; temp_i = temp_i+1)
{
numbers[element]=temp_array[temp_i]
numbers[element+1] = temp_array[temp_i + N]
element = element+2
}
}
//For last group
if(last_group_len ==0) return
temp_array = numbers.slice(groups_of_2n_len*2*N,/*Till Last element*/)
element = groups_of_2n_len*2*N
for(temp_i = 0; temp_i< floor(last_group_len/2); temp_i = temp_i+1)
{
numbers[element]=temp_array[temp_i]
numbers[element+1] = temp_array[temp_i + floor(last_group_len/2)+last_group_len%2]
element = element+2
}
//In case of odd number of elements, no need to handle
//last element since it is already in correct place
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Example highlighted:
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
return a - b;
});
console.log(numbers);
// [1, 2, 3, 4, 5]
If numbers are in two separate arrays you can do something like this...
const array1 = [0, 4, 6, 5, 7];
const array2 = [1, 3, 2, 8, 9];
const combined = [...array1, ...array2];
console.log(combined);
I have six integers stored in an array:
[2,3,4,5,6,7]
I would like to use each item in the array to check against a range of other integers 100 - 999 (i.e. all three-digit numbers) to find a number that has a remainder of 1 when divided by all the items in the array individually.
I'm not sure what javascript method to use for this. I'm trying a for loop:
function hasRemainder() {
let arr = [2,3,4,5,6,7];
for (i = 100; i < 999; i++) {
if (i % arr[0] == 1) {
return i;
}
}
}
but it has several problems I need to solve.
Instead of referring to a particular item e.g. arr[0], I need to find a way to loop through all the items in the array.
Currently, this function only returns one number (the loop stops at the first number with a remainder), but I need all the possible values in the given range.
If anyone could help with these two problems, I'd really appreciate it. Thanks.
You could map an array of values and then filter the array by checking every remainder value with one.
function hasRemainder() {
var array = [2, 3, 4, 5, 6, 7];
return Array
.from({ length: 900 }, (_, i) => i + 100)
.filter(a => array.every(b => a % b === 1));
}
console.log(hasRemainder())
This works also;
function hasRemainder() {
const arr = [2, 3, 4, 5, 6, 7];
const remainders = []
for (i = 100; i < 999; i++) {
const isRemainder = arr.every(numb => i % numb === 1)
if (isRemainder) {
remainders.push(i)
}
}
return remainders
}
This question already has answers here:
How can I remove a specific item from an array in JavaScript?
(142 answers)
Closed 4 years ago.
So im trying to remove the numbers 1,2,7,14 in the array but i dont know how to remove it. I did not find any solution that is similar to this
function mySelect(){
var prime1 = document.getElementById('input1').value;
var prime2 = document.getElementById('input2').value;
var n = prime1 * prime2;
console.log(n);
var foo = new Array(n);
console.log(foo.length);
var range = [];
for(var i=1;i<foo.length;i++){
range.push(i);
}
console.log(range);
// --------------------------------------------//
var half = Math.floor(n / 2), // Ensures a whole number <= num.
str = '1', // 1 will be a part of every solution.
i, j;
// Determine our increment value for the loop and starting point.
n % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);
for (i; i <= half; i += j) {
n % i === 0 ? str += ',' + i : false;
}
str += ',' + n; // Always include the original number.
console.log(str);
}
After you pushed the values to the array you can use a filter function, like so:
let nonos = [ 1, 2, 7, 14 ];
range = range.filter((element) => !nonos.includes(element));
This code specifies the values you want removed inside an array and then runs a loop on your original array and checks whether the element you're on is included in your nonos array and if it is, don't include it in your original array, else do.
To remove all instances of the provided numbers from an array:
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function removeNumbers(array, ...numbers) {
numbers.forEach((number) => {
var index = array.indexOf(number);
while(index >= 0) {
array.splice(index, 1);
index = array.indexOf(number);
}
});
}
removeNumbers(array, 3, 2, 5, 7);
console.log(array);
find the index first and then apply splice method.
var array=[1,2,3,4,5,6,7,8,9,10]
console.log(array)
find the index of value you want to delete
let indexa=array.indexOf(2);
apply splice method to delete 1 value from applied index
array.splice(indexa,1);
console.log(array)
I have an array of array with elements for example:
var one = [1span,2span,3span,4span,5span,6span,7span];
var two = [1span,2span,3span,4span,5span,6span,7span];
var three = [1span,2span,3span,4span,5span,6span,7span];
var ...till seven.
var total = [one,two,three ..till 7]
so basically we have 7 arrays and total variable will display 7 elements for each one of all 7 arrays.
now I have a function that should populate my variables with distinct numbers from 1 to 7 on each section.
var bar = [1, 2, 3, 4, 5, 6, 7];
for(var j=0; j<total.length; j++) {
Array.from(total[j]).forEach(function(e, i, a) {
e.textContent = bar[Math.round(Math.random()*(bar.length-1))];
console.log(e,i,k);
});
}
all good my function does that but unfortunately is populating span elements with values from bar variable for each variable from total var 7 times for each and should populate just once for each variable.
So my problem is:
I want to populate each variable from total var with values from bar array just once.
The values should be randomly and unique for each variable.
You could use an copy of the given array and generate random items without repeat.
function generate(count, values) {
return Array.apply(null, { length: count }).map(function () {
var r = [],
array = values.slice();
while (array.length) {
r.push(array.splice(Math.floor(Math.random() * array.length), 1)[0]);
}
return r;
});
}
console.log(generate(7, [1, 2, 3, 4, 5, 6, 7]));
Randomize a single array
function generate(values) {
var r = [],
array = values.slice();
while (array.length) {
r.push(array.splice(Math.floor(Math.random() * array.length), 1)[0]);
}
return r;
}
console.log(generate([1, 2, 3, 4, 5, 6, 7]));
If we would like to extend the question for a general case of an N dimensional array filled with random integers then a reusable approach could be as follows;
We will use two generic functions that i like to use very much; Array.prototype.clone() and Array.prototype.shuffle(). Our arrayND function takes indefinite number of arguments. The last argument will designate the minimum (base) of the random integer to be filled. Previous arguments will give the length of each dimension. So in the particular case as we will need a 2D 7x7 matrice to be filled with random but unique numbers in each starting from 1, we shall invoke our function as arrayND(7,7,1)
Array.prototype.shuffle = function(){
var i = this.length,
j;
while (i > 1) {
j = ~~(Math.random()*i--);
[this[i],this[j]] = [this[j],this[i]];
}
return this;
};
Array.prototype.clone = function(){
return this.map(e => Array.isArray(e) ? e.clone() : e);
};
function arrayND(...n){
return n.reduceRight((p,c) => c = Array(...Array(c)).map((e,i) => Array.isArray(p) ? p.clone().shuffle() : i+p));
}
var arr = arrayND(7,7,1);
console.log(arr);
since you want these Arrays to be processed together you should put them together into a data-structure:
var spans = [ one, two, tree, ..., seven ]
now you want a random order without repetition, put the possible indices into an Array and shuffle that:
var indices = [0,1,2,3,4,5,6];
and some shuffler:
function shuffle(arr){
for(var i=arr.length, j, tmp; i-- > 1; ){
tmp = arr[j = 0|(Math.random()*i)];
arr[j] = arr[i];
arr[i] = tmp;
}
return arr;
}
now if you want the Nodes for total:
var total = shuffle(indices).map((index, n) => spans[n][index]);
at least as far as I understand your question/code/intentions.