In Kotlin refenrence, it is written as multiple conditions can be matched using comma (,) inside a when control flow. For example-
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
Here, in the first condition comma works like an OR operator.
Is there any way to write an expression to match AND condition inside when?
Yes. Although the syntax is somewhat different:
when {
x % 5 == 0 && x % 3 == 0 -> println("foobar")
x % 5 == 0 -> println("bar")
x % 3 == 0 -> println("foo")
}
Related
So I am fairly new to Kotlin and I need to generate specific numbers from a for loop of 1 to 13.
For the first output I need only odd numbers
For the second output I need numbers 2, 5, 8, 11, 14, 19 and 20 from a for loop of 0 to 20
For starters I can print an entire list using:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
for (i in 1..13){
println(i)
}
}
}
But that's it. What do I need to print the other required outputs?
Once you know how to write a for loop that prints every number, the question becomes how to identify a number that you "should" print from a number that you should not.
Your first sequence is all odd numbers, so #DipankarBaghel's answer covers that. Your second sequence seems to be all numbers for which the remainder when dividing by 3 is 2. (Except 19; did you mean 17 for that one?)
You can use the same operator in this case, but instead of checking for 0 (or for != 0) you can check that the remainder is 2:
for (i in 0..20) {
if (i % 3 == 2) {
println(i)
}
}
The key concept here is that of %, the remainder operator (sometimes called the modulo operator). The result of x % y will be the remainder when x is divided by y. Odd numbers have a remainder of 1 when divided by 2, so i % 2 == 1 will be true only for (positive) odd numbers.
To check even you need to do i%2==0 and for odd just check i%2!=0.
for (i in 1..13){
if(i%2!=0){
println("odd number "+i);
}
if(i%2==0){
println("even number "+i);
}
}
Hope this will help you.
To generate Odd numbers:
for (i in 1..13) {
if(i % 2 == 1 ){
println(i + ", ");
}
}
To Generate 2, 5, 8, 11, 14, 19 and 20:
for (i in 0..20) {
if (i % 3 == 2) {
println(i + ", ");
}
}
When I check the keyCodes on the softKeyboard for .- , the e.key in JavaScript is "Unidentified" and the e.keyCode is 229 for all of those characters.
The device I am using is a TC52k scanner and the scan trigger has the same key and keyCode... so it can't be completely disabled.
I don't know how many things I tried that didn't work... but I will post some...
This is a dynamic field bound with rivets.js using JSON objects
$(document).on("keydown", ".qty-input", function(e) {
let code = e.keyCode;
if (code == 229 && $(this).val().charAt(str.length - 1) == ".") {
$(this).val($(this).val().slice(0, -1));
}
});
^Basically, that says that if the last character has the code 229 and the last character of the entered string is a '.', then cut the last character off... but doesn't work correctly.
I also did this that basically says to only accept keys that have keycodes between 48 and 57 which are keys 1-9 on the android soft keyboard.
<input class="qty-input" placeholder="0" type="number" min="0" step="1" onkeypress="return event.charCode >= 48 && event.charCode <= 57 && event.keyCode != 229" pattern="[0-9]*" autofocus>
Also didn't work...
Does anyone have experience with this and can help?
I know there's lots of unsolved posts about this online.
It's the last thing I have to do and its keeping my app from being deployed!
Also... I've tried these function using events: keyup, keydown, change, input and keypress...
Here is the best workaround that I found (since 229 also triggers the 'scanner' trigger, I have to detect whether a string includes a barcode and a quantity and will have to separate the two(the keyCode for a [.] again is the same as the keyCode for the scanner trigger))
The 2 conditions determine 2 things:
If the value is longer than 3, then it is not allowed as a quantity because the quantity can not be over '500', so when it has a length longer than 5, it is considered to be a barcode.
let oldVal = '';
let newVal = '';
let barcode = '';
$(document).on("keydown", "input.received-qty", function(e) {
let code = e.keyCode || e.which || e.charCode;
oldVal = $(this).val();
});
$(document).on("keyup", "input.received-qty", function(e) {
let code = e.keyCode || e.which || e.charCode;
newVal = $(this).val();
if (code == 229 && e.target.value.length >= 3) {
barcode = $(this).val().slice(oldVal.length - 1, -1);
$(this).val(oldVal);
} else if (code == 229 && e.target.value.length <= 3) {
let x = oldVal.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "");
$(this).val('');
$(this).val(x);
}
console.log("oldVal : ", "[", oldVal, "]", "newVal : ", "[", $(this).val(), "]");
});
This is the best way I've tried so far.
I am trying to implement a bus seat booking application which is very similar to RedBus app. I came across over the seating arrangement in that and i was struck over there.
I really need your help in achieving this. I have tried with Recycler View but that doesn't get me into the exact layout.
I have tried with recycler view and my layout goes as,
But, the actual screen shot from redbud application is as,
I have gone through one of the code that is available in git
https://github.com/TakeoffAndroid/SeatBookingRecyclerView
But, using the above code, i can get the layout design but the problem with this is, Say like if there are 41 seats, but using the above git code it will be showing 33 seats on the screen comes up like as,
Help would be really appreciated.
Snippet Code:
numOfColumns = 4;
mArrayBusSeats = new ArrayList<>();
for (int i = 0; i < mArraySeats.size(); i++) {
if (i % numOfColumns == 0 || i % numOfColumns == (numOfColumns - 1)) {
BusLayoutModel model = mArraySeats.get(i);
model.setSeatType(AbstractItem.TYPE_EDGE);
mArrayBusSeats.add(model);
} else if (i % numOfColumns == 1 || i % numOfColumns == (numOfColumns - 2)) {
BusLayoutModel model = mArraySeats.get(i);
model.setSeatType(AbstractItem.TYPE_CENTER);
mArrayBusSeats.add(model);
} else {
BusLayoutModel model = new BusLayoutModel();
model.setSeatType(AbstractItem.TYPE_EMPTY);
mArrayBusSeats.add(model);
}
}
In your example, your recyclerview has 3 viewTypes - TYPE_EDGE, TYPE_CENTER, TYPE_EMPTY i.e, seats are of 3 types. As in your question
Say like if there are 41 seats, but using the above git code it will be showing 33 seats
Infact this is the expected behaviour since your recyclerview consists of a viewtype - TYPE_EMPTY which prints an empty view. So if you give 41 seats only 33 will be visible since the rest of the seats are of type TYPE_EMPTY . If you count the empty positions in your recyclerview as well, then you can see that the total will be 41.
In your Recycler View implementation try to reduce row height, as compared to redbus your row height is almost double.
Have you tried with the number of column 5 ??
I haven't use the library but when I checked it I think I should be done like this
numOfColumns = 5;
mArrayBusSeats = new ArrayList<>();
for (int i = 0; i < mArraySeats.size(); i++) {
BusLayoutModel model = mArraySeats.get(i);
if (i % numOfColumns == 0 || i % numOfColumns == 4) {
model.setSeatType(AbstractItem.TYPE_EDGE);
mArrayBusSeats.add(model);
} else if (i % numOfColumns == 1 || i % numOfColumns == 3) {
model.setSeatType(AbstractItem.TYPE_CENTER);
mArrayBusSeats.add(model);
} else {
model.setSeatType(AbstractItem.TYPE_EMPTY);
mArrayBusSeats.add(model);
}
}
On Android using CouchDB with CouchBase Lite I am trying to replicate a database also I use filter in order to get documents with a field whose name is device_number
So I have this filter:
"1": "function(doc, req) {
if(doc.ismaster || doc._deleted)
return false;
if( 1 == doc.device_num || 22 == doc.device_num || 25 == doc.device_num || 41 == doc.device_num )
return true;
else
return false;}",
It works perfectly and I get all the documents for the devices: 1, 2 , 25 ,41.
Well now I want to get documents for device_num = 22 and 21 and whose creation_date has less than 60 days from the present day so I do:
"1": "function(doc, req) {
if(doc.ismaster || doc._deleted)
return false;
if( 22 == doc.device_num && 21 == doc.device_num && (Math.ceil((new Date(Date.now()).getTime() - new Date(doc.creation_date.split('/')[2], doc.creation_date.split('/')[1] - 1, doc.creation_date.split('/')[0]).getTime()) / (1000 * 3600 * 24)) <= 60) )
return true;
else
return false;}",
but I am not getting results, 0 documents, and is not true because in the database there are documents with less than 60 days.
what I am doing wrong?
I want to get documents for device_num = 22 and 21 and whose
creation_date has less than 60 days from the present day
English wording: "I want documents for 21 and 22" is actually "I'll accept any document where the document is for either 21 or 22":
if( (22 == doc.device_num || 21 == doc.device_num) && ...)
as no document with a single device_num can simultaneously be for devices 21 and 22.
Dates are a bit of a mess around the world and who knows if your user's are in the same time zone? Couchdb provides some examples of considering collation factors in dates, and here is an example of using number type for safe collation:
// creation:
{tstamp:+new Date(), device_num:22, ...}
// test
validstamp = +new Date() - 1000*60*60*24*60;
if( (22 == doc.device_num || 21 == doc.device_num) && Number(doc.tstamp) > validstamp)
...
Its nice to use Number() in case something went wrong in storage and you have stored a string. But as numbers, they are logically sequential without oddities of non-zero padded strings around the early 1980s and the distant future and you can later refactor to using mango indexes with:
{
"tstamp": {'$gt':validstamp},
"$or": [
{ "device_num": 21 },
{ "device_num": 22 }
]
}
As default, an Android EditText will break a line if the line is longer than the view, like this:
Thisisalineanditisveryverylongs (end of view)
othisisanotherline
or if the line contains a punctuation character, like this:
Thisisalineanditsnotsolong; (several characters from the end of view)
butthisisanotherline
As a requirement of my work, the text has to break a line only if the line is longer than the view, like this:
Thisisalineanditsnotsolong;andt (end of view)
hisisanotherline
There must be a way to achieve this, am I right? So far I haven't found anyway to do this.
The way TextView (and EditText) breaks the text is through private function calls to BoringLayout internally. So, the best way would be to sublcass EditText and rewrite these functions. But it will not be a trivial task.
So, in the TextView class there are creations of different classes for text style. The one we look is DynamicLayout. In this class we reach to a reference of the class StaticLayout (in a variable called reflowed). In the constructor of this class you will find the text wrap algorithm:
/*
* From the Unicode Line Breaking Algorithm:
* (at least approximately)
*
* .,:; are class IS: breakpoints
* except when adjacent to digits
* / is class SY: a breakpoint
* except when followed by a digit.
* - is class HY: a breakpoint
* except when followed by a digit.
*
* Ideographs are class ID: breakpoints when adjacent,
* except for NS (non-starters), which can be broken
* after but not before.
*/
if (c == ' ' || c == '\t' ||
((c == '.' || c == ',' || c == ':' || c == ';') &&
(j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
((c == '/' || c == '-') &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
(c >= FIRST_CJK && isIdeographic(c, true) &&
j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
okwidth = w;
ok = j + 1;
Here's where all the wrapping goes. So you will need to subclass take care for StaticLayout, DynamicLayout, TextView and finally EditText which - I am sure - will be a nightmare :( I am not even sure how all the flow goes. If you want - take a look at TextView first and check for getLinesCount calls - this will be the starting point.
This Line Breaking algorithm in Android really sucks, it isn't even logically correct - a comma can not be the last character of a line. it only produces unnecessary line breaks, which results in extremely weird text layout.
Hi Here is one method I first get from another guy and then make a little bit changes, it really works for me you can have a try.
//half ASCII transfer to full ASCII
public static String ToSBC(String input) {
char[] c = input.toCharArray();
for (int i = 0; i< c.length; i++) {
if (c[i] == 32) {
c[i] = (char) 12288;
continue;
}
if (c[i]<=47 && c[i]>32 )
c[i] = (char) (c[i] + 65248);
}
return new String(c);
}
}
here it is. I change some special characters from half corner to full corner, such as "," ".", and the effect is pretty good. You can have try.