pagination in javascript showing amount of elements per page - javascript

${totalItems} = 22
${pageSize} = 10
I would like to know how can I create a calculation.
like that: first will show 1 - 10 items, if i click in the next page will show: 11 - 20 and the last one will be 21 - 22.
so basically the calculation will be showing the numbers 1 -10 then 11-20 everytime i click in the next page in my pagination.
can someone give a javascript sample for this? the only value I have is 22, so I would like do a calculation like I said above. and display this in my html.

Getting the index of the first item on a page
To get the first index of a page, you multiple the current page number by the number of items per page:
firstIndex = pageSize * pageNr
For your example:
console.log(
"Start of each page:",
[0, 1, 2].map(pageNr => 10 * pageNr)
);
Getting the index of the last item on a page
To get the index of the last item in a page, we can use this function to get the starting index of the next page, and subtract 1:
lastIndex = pageSize * (pageNr + 1) - 1
console.log(
"End of each page:",
[0, 1, 2].map(pageNr => 10 * (pageNr + 1) - 1)
);
Finding out how many pages there are
To see how many pages we need to render all our items, we divide the total number of items by the page size and round upwards using Math.ceil:
nrOfPages = Math.ceil(nrOfItems / pageSize)
Writing the actual code
Now that we've got the basic "math" covered, we can start writing actual functions and create a small app.
Depending on the format of the data, you can build some safety checks to make sure you cannot:
Request a page number that is out of range,
Request a negative page number
Input a 0 or negative page size,
etc.
Since you haven't provided anything useful to work with, I'm going to skip these measures and show you an example based on one array of items to paginate:
function getPageStart(pageSize, pageNr) {
return pageSize * pageNr;
};
function getPageLabel(total, pageSize, pageNr) {
const start = Math.max(
getPageStart(pageSize, pageNr),
0
);
const end = Math.min(
getPageStart(pageSize, pageNr + 1),
total
);
return `${start + 1} - ${end}`;
}
const itemsToShow = Array.from({ length: 22 }, (_, i) => `Item ${i + 1}`);
const size = 10;
const pages = Array.from(
{ length: Math.ceil(itemsToShow.length / size) },
(_, i) => getPageLabel(itemsToShow.length, size, i)
)
console.log(pages);

Related

vue.js pagination mis calculation

In my app, I have some pagination code which calculates the pagination based on data from a REST API. When I add the page of pages, it is calculating from page 0 not from 1, so it says 0 of 9 and when it gets to the end it says 8 of 9, when it should say 1 of 9 and 9 of 9 at the end. So far my code is:
HTML
<p>Page {{page}} of {{pageCount}}</p>
JS
data: function() {
return {
page: 0
};
},
computed: {
pageCount() {
let l = this.result.length,
s = this.size;
return Math.floor(l / s);
},
paginated() {
const start = this.page * this.size,
end = start + this.size;
return this.result.slice(start, end);
}
},
Any ideas? Maybe I am calculating the math.floor method wrong?
Your page variable is 0 indexed instead of 1 index. You can keep it this way so that your pagination continues to work as intended, but where you are outputting it to the user you can simply add 1 so it makes sense to a user.
<p>Page {{page + 1}} of {{pageCount}}</p>
From what I understood, your pageCount() method is correct because you indeed have 9 pages so math.floor is not the problem, your page variable is the one that is incorrect but I cannot see where you are getting that variable from but a simple yet coarse solution would be just to add 1 to the variable.

javascript making change algorithm

I'm solving this problem "Making change" in javascript:
Question:
Given an amount of money, an array of coin denominations, compute the
number of ways to make the amount of money with coins of the available
denominations.
Example:
For amount=4 (4¢) and denominations=[1,2,3] (1¢,
2¢ and 3¢), your program would output 4—the number of ways to make
4¢ with those denominations:
1¢, 1¢, 1¢, 1¢
1¢, 1¢, 2¢
1¢, 3¢
2¢, 2¢
I found a solution:
var makeChange = function(total){
var count = 0;
var coins = [1, 2, 5, 10, 20, 50, 100, 200];
var changer = function(index, value){
var currentCoin = coins[index];
if( index === 0){
if( value % currentCoin === 0){
count++;
}
return;
}
while( value >= 0 ){
changer(index-1, value);
value -= currentCoin;
}
}
changer(coins.length-1, total);
return count;
};
makeChange(200);
Problem(s):
Can someone explain to me what is going on? I tried following the code but i get lost in between the recursion.
I understand that he is taking the final coin value and he is substracting from the given total. (But why?) I'm kinda lost.
When value >= 0 in the while loop, It keeps looping around increasing the index, i couldn't understand why.
Can someone make sense out of this algorithm?
Sorry, just started learning Dynamic Programming.
Thank you,
Let's track what happens with makeChange(4):
The function changer gets defined then called for the first time.
value = 4, index = 7, coins[7] = 200
Since the variable, index is not 0, we move on to the while loop.
A second call to changer is made with index 6
Meanwhile, the first call continues the 'while'
loop but since 200 has been subtracted from 'value',
'value' is now less than 0 so the 'while' loop terminates
and this first call does nothing more.
(Keep in mind that the variable 'value' is distinct
and private to each call, so the 'while' loop only
affects the 'value' in its own function call.)
Ok, now this pattern continues with all the function calls that have index pointing to a coin larger than value until index is 1.
value = 4, index = 1, coins[1] = 2
This time more happens in the while loop:
We get the function call, 'changer(0,4)',
AND a second function call, 'changer(0,2)',
after we subtract 2 from 'value', which was 4,
AND a third function call, 'changer(0,0)',
after we subtract 2 from 'value', which was 2.
These 3 calls respectively represent:
1 + 1 + 1 + 1
2 + 1 + 1
2 + 2
Each time the line 'value -= currentCoin' is executed,
it represents the start of another set of choices for
solutions that include that coin.
4 % coins[0] = 0, meaning 4 is divisible by 1 represents 1 + 1 + 1 + 1
4 - 2 folllowed by 2 % 1 represents 2 + 1 + 1
and 4 - 2 - 2 represents 2 + 2
Total count: 3

Find number of pairs with difference larger than or equal to given number

I have a array/dict(HashMap) of positive integers.
I need to find the number of pairs that have a absolute difference greater or equal to a given number, K.
import random
import time
#given number
k = 4
# List of 2,00,000 random numbers in range 0-1000
strength = [random.randrange(0,1000) for x in range(200000)]
strength.sort()
# start clock
start1 = time.clock()
n = len(strength)
# count keeps track of number of pairs found
count = 0
for x in range(n):
for y in range(x,n):
if abs(strength[x] - strength[y]) >= k:
# if found, all number from this point to the end will satisfy
count += n-y
# So no need to go to the end
break
end1 = time.clock()
print(count)
print(end1-start1)
All the answers I find are for pairs less than or equal to a given number.
I need to find the number of pairs that have a absolute difference greater or equal to a given number, K.
Note that the total number of pairs is n * (n - 1) / 2, so if you can find the number of pairs with difference less than K, the number of pairs with difference greater than K is just n * (n - 1) / 2 - num_pairs_with_diff_less_than_K
The solution you provide is also correct (and well documented). If your question is how to adapt it to your case, then all you need to do is to use values of your HashMap (sorted) instead of the strength array.
You can get the 2 item combinations of the array and then filter / reduce them according to the difference.
One might do the job in JavaScript as follows;
Array.prototype.combinations = function(n){
return this.reduce((p,c,i,a) => p.concat(n > 1 ? a.slice(i+1).combinations(n-1).map(e => (e.push(c),e))
: [[c]]),[]);
};
function getAcordingToDiff(a,d){
return a.combinations(2)
.reduce((p,c) => Math.abs(c[0]-c[1]) >= d ? (p.push(c),p) : p ,[]);
}
var arr = Array(30).fill().map((_,i) => i+1); // array from [1,...,30]
console.log(JSON.stringify(arr))
console.log(JSON.stringify(getAcordingToDiff(arr,25))); // diff >= 25
Explanation:
So in the heart of the above code obviously lies the Array.prototype.combinations function. For those who are not familiar with JS, this is just an ordinary function that we define under the Array object's prototype (so that now every array has access to this function like arr.combinations(n)) But let's use a more expressive language and refactor the above combinations array method into a generic function.
function combinations(a,n){
var sa;
return a.reduce(function(p,c,i,a){
if (n > 1) sa = combinations(a.slice(i+1), n-1).map(e => (e.push(c),e));
else sa = [[c]];
return p.concat(sa);
},[]);
}
So as you will notice combinations(a,n) is a recursive function which takes an array a and items count n. It works on the basis of keeping the first item of the input array and recursively invoking itself with one item shorter array, combinations(a.slice(i+1), n-1), and with one less items count up until n decrements to 1 in which case it starts it's return cycle with whatever remains from the input array and each item is wrapped in an array, sa = [[c]].
So on the return cycle of the recursive calls we take the resulting array and push the kept first element (remember -> It works on the basis of keeping the first item of the input array) into each item of the returned array (remember -> ...and each item is wrapped in an array, sa = [[c]]).
So that's it... You should be able to figure out yourself the details.
However in our application we are given an array of numbers and requested to obtain only the 2 item combinations with a certain difference. In this particular case we don't need to calculate all combinations and then filter them. We can do this on the way constructing our combinations. As the required difference value d gets bigger this will bring in a huge gain over filtering afterwards method, since now as d gets bigger we are eliminating more and more of the two item combinations, even before we generate them. And... let's hard-wire our code to work with 2 items only and merge everything in a single function. The performance results are below;
function getCombosWithDiff(a, d, n = 2){
var sa;
return a.reduce(function(p,c,i,a){
if (n > 1) sa = getCombosWithDiff(a.slice(i+1), d, n-1).reduce((r,e) => Math.abs(e[0]-c) > d ? (e.push(c),r.push(e),r)
: r, []);
else sa = [[c]];
return p.concat(sa);
},[]);
}
var arr = Array(100).fill().map((_,i) => i+1);
result = getCombosWithDiff(arr,89);
console.log(JSON.stringify(arr));
console.log(JSON.stringify(result));
So that's it. I have tried the above code to list the 2 items combinations each with diff greater than 10 from an array of 1000 items. It takes like 5000 msecs in Chrome and 14000 msecs in FF. However as mentioned above, the more the diff value d gets bigger, the shorter it takes. e.g same array with diff 900 would resolve in just 1100msecs with Chrome and in 4000msecs with FF.
You can test and play here
Create a 1001-element array A of integers initialized to zeroes. Generate your random integers, and increment the appropriate index by 1 for each such integer. With some math, you could do this without generating 2,000,000 random integers, but it's not worth the complexity.
Create a second 1001-element integer B s.t. B[i] = A[0] + ... + A[i]
Answer is sum from i=0 to 1000-k of B[i] * (2,000,000 - B[i+k-1])

javascript get random number: lower probability to get higher number in the interval

Ok, so I have very big array of numbers in javascript:
[1, 1.01, 1.02, 1.03, ..., 1.99, 2, ..., 9.98, 9.99, ..., 299.99, 300]
And what I need is to get one of them using random segment. So basically I need random number but the catch is that I need to get random using the lottery style. So the chance to get "1" will be 30 000 (very hight) and the chance to get 1.01 will be 29 999. But the chance to get 300 will be very low according of all numbers in this array.
I hope you will understand the problem and will help me to solve this. As I have mentioned before, this have to be made 100% randomly and I have no idea how to make it..
The solution I had so far:
I was trying to expanse the array by adding multiple same numbers and lower the count of it by each step. So I have added 30000 units of 1 and 29999 units of 1.01 ... and 2 units of 299.99 and one unit of 300. But the array got very large and I came here to find better solution.
Also I have found this: https://stackoverflow.com/a/13758064/5786106
and it seems to be the answer to me but I don't know how to use it with the decimal system (0.01, 0.02, ... 0.99)
var num = Math.pow(Math.floor(Math.random()*10), 2);
One solution would be to make the very large array you propose, but to make it imaginary, without ever constructing that object in code.
How long will the imaginary array be? Well your array has (300 - 1) * 100 + 1 = 29,901 elements in it. Then there are (29,901 + 1) * (29,901 / 2) = 447,049,851 elements in the imaginary array. So the first step is to generate a random integer between 0 and 447,049,850:
var imaginaryIndex = Math.floor(Math.random() * 447049851);
The next step is to determine which real index in your original array corresponds to the imaginaryIndex in the imaginary array.
var indexFromEnd = 0;
while((indexFromEnd + 2) * ((indexFromEnd + 1) / 2) < imaginaryIndex)
indexFromEnd++;
Finally, you need to calculate the value of the element in your array based on where it is in your array:
return 300 - (indexFromEnd * 0.01);
Now let's clean that up and put it in a nice, reusable function:
function triangularWeightedRandomSelect(myArray){
var imaginaryIndex =
Math.floor(Math.random() * (myArray.length + 1) * myArray.length / 2);
var indexFromEnd = 0;
while((indexFromEnd + 2) * ((indexFromEnd + 1) / 2) < imaginaryIndex)
indexFromEnd++;
return myArray[myArray.length - 1 - indexFromEnd];
}

How to calculate balanced tiers on ranked values

I have an array of ranked values that I would like to group by x number of tiers for a given report. In this example, I have a list of 20 items and would like to calculate a total of 5 tiers so that the tiers are as evenly spread out as possible. In other cases, there might be a total of 31 items and 4 tiers. How could I write a function to handle this? Below are sample data and what the calculated tier for each item should be.
The reason why I would like to do this is to examine a difference in trends based upon the volume of included metrics. The table above is an example only because the data I am actually working with is not something I can share.
UPDATE
After some testing, this is the function I came up with:
function getTier(num_tiers, arr_length, rank){
var c = Math.floor(arr_length / num_tiers, 1),
m = (rank - 1) % c;
var result = Math.floor(((rank / c) - (m / c)) + 1, 0);
return (result > num_tiers) ? num_tiers : result;
}

Categories