问题
I hope I'm overthinking this and there's an obvious solution.
From the API (GET statuses/user_timeline)
max_id - Returns results with an ID less than (that is, older than) or equal to the specified ID.
"or equal to" means it will include the tweet with ID that I sent as my max_id parameter.
--
My question is this: if I store the id of my oldest tweet (from a previous request), how can I subtract 1 from this id to exclude it from being returned in my next request?
The obvious solution would be to do something like this '&max_id='+lastID-1, but twitter IDs are way to large for such math operations and javascript rounds off the results.
Details about the snowflake update: https://dev.twitter.com/docs/twitter-ids-json-and-snowflake
Posible solutions:
It has been mentioned that I can use the BigInteger Javascript Library: http://silentmatt.com/biginteger/, but in my opinion this is redundant for such as small task.
Do I have to use recursion on the string (id_str) and increment or decrement it by one? I hate to use a hack for such as small detail that should just work.
--
If you've had this problem please share your solution.
thanks!
回答1:
I ran into this same problem, and ended up solving it by subtracting 1 from the last digit, and then accounting for the scenario when we're subtracting 1 from 0 via recursion.
function decrementHugeNumberBy1(n) {
// make sure s is a string, as we can't do math on numbers over a certain size
n = n.toString();
var allButLast = n.substr(0, n.length - 1);
var lastNumber = n.substr(n.length - 1);
if (lastNumber === "0") {
return decrementHugeNumberBy1(allButLast) + "9";
}
else {
var finalResult = allButLast + (parseInt(lastNumber, 10) - 1).toString();
return trimLeft(finalResult, "0");
}
}
function trimLeft(s, c) {
var i = 0;
while (i < s.length && s[i] === c) {
i++;
}
return s.substring(i);
}
回答2:
Indeed, Twitter API will respond with a duplicate tweets unless we decrease max_id parameter.
Here is a nice Twitter API article on max_id: https://dev.twitter.com/docs/working-with-timelines On general concept of working with a large (more than 53-bit) numbers in JavaScritp: http://www.2ality.com/2012/07/large-integers.html
Back to the question: using a library seems like an overkill unless you use it for something else. @bob-lauer has a good lightweight solution but I've written my own function without the recursion:
function decStrNum (n) {
n = n.toString();
var result=n;
var i=n.length-1;
while (i>-1) {
if (n[i]==="0") {
result=result.substring(0,i)+"9"+result.substring(i+1);
i --;
}
else {
result=result.substring(0,i)+(parseInt(n[i],10)-1).toString()+result.substring(i+1);
return result;
}
}
return result;
}
To test it run with the following numbers/strings:
console.log("290904187124985850");
console.log(decStrNum("290904187124985850"));
console.log("290904187124985851");
console.log(decStrNum("290904187124985851"));
console.log("290904187124985800");
console.log(decStrNum("290904187124985800"));
console.log("000000000000000001");
console.log(decStrNum("0000000000000000001"));
回答3:
Here is a quick'n'dirty PHP version of @Azat's answer of a non-recursive function to decrement a long string-format (non-negative) integer.
<?php
function decStrNum($n)
{
$n = (string)$n;
if ((int)$n == 0 || 0 === strpos($n, '-'))
return false;
$result = $n;
$len = strlen($n);
$i = $len - 1;
while ($i > -1) {
if ($n[$i] === "0") {
$end = substr($result, $i + 1);
if ($end === false) $end = '';
$result = substr($result, 0, -($len - $i)) . "9" . $end;
$i--;
} else {
$end = substr($result, $i + 1);
if ($end === false) $end = '';
return substr($result, 0, -($len - $i)) . ((int)$n[$i] - 1) . $end;
}
}
return $result;
}
来源:https://stackoverflow.com/questions/9717488/using-since-id-and-max-id-in-twitter-api