Categories
discuss

Java 8 mapToInt and toIntFunction examples

i am testing the new major update from Java A.K.A Java 8 is very interesting. i am using streams in particular i am using this simple code.

private void getAvg()
{
    final ArrayList<MyPerson>persons = new ArrayList<>
    (Arrays.asList(new MyPerson("Ringo","Starr"),new MyPerson("John","Lennon"),new MyPerson("Paul","Mccartney"),new MyPerson("George","Harrison")));                
    final OptionalDouble average = persons.stream().filter(p->p.age>=40).mapToInt(p->p.age).average();
    average.ifPresent(System.out::println);        
    return;
}            
private class MyPerson
{
    private final Random random = new Random();
    private final String name,lastName;
    private int age;
    public MyPerson(String name,String lastName){this.name = name;this.lastName = lastName;this.age=random.nextInt(100);}    
    public MyPerson(String name,String lastName,final int age){this(name,lastName);this.age=age;}    
    public String getName(){return name;}
    public String getLastName(){return lastName;}                   
    public int getAge(){return age;}        
}            

in this example i understand very clear but later i have seen also can accomplish it in this way.

final OptionalDouble average = persons.stream().filter(p->p.age>=40)
.mapToInt(MyPerson::getAge).average();
average.ifPresent(System.out::println);        

i have checked the method toIntFunction and in fact have the following signature.

@FunctionalInterface
public interface ToIntFunction<T> {

/**
 * Applies this function to the given argument.
 *
 * @param value the function argument
 * @return the function result
 */
int applyAsInt(T value);
}

as i can see the applyAsInt have a input and returns a int as long as i understand

this code

MyPerson::getAge

calls

public int getAge(){return age;}//please correct me at this point        

my question is.. the method getAge have not parameters and returns a int but the toIntFunction receive a parameter this is the part i dont understand.

the parameter from toIntFunction is inferred or something

any help is hugely appreciate..

thanks a lot

Answer

Remember a method reference is just a shortcut for a lambda. So an instance method reference is a lambda that calls that method on the argument. The type of the argument is the class given in the method reference. It helps to “unwrap” it.

MyPerson::getAge

Unwrap to a lambda:

(MyPerson p) -> p.getAge()

Unwrap to an anonymous class:

new ToIntFunction<MyPerson>() {
    @Override
    public int applyAsInt(MyPerson p) {
        return p.getAge();
    }
}

With a static method reference, the signature must match exactly, that is, the static method takes a T and returns an int. With an instance method reference, the parameter T of the lambda is the object the method gets called on.

Categories
discuss

Simple node.js readline on the console

I’d like to teach students how to program using JavaScript. I don’t want to introduce new students to call-backs or any other complex program structure. Looking at Node.js the readline used for standard input uses a call-back. For simple input data, then do a calculation, I’d like a simple equivalent to an input like Python or other similar languages have:

width = input("Width? ")
height = input("Height? ")
area = width * height
print("Area is",area)

Is there some way to do this with JavaScript?

Answer

The module readline-sync, (source can be found here, npm page here) will do what you want, it looks like.

If you’d prefer to work at a lower level, it looks like it works by passing the stdin file descriptor (stdin.fd) to the synchronous fs methods. For example:

fs.readSync(stdin.fd, buffer, 0, BUF_SIZE)
Categories
discuss

Angular is automatically adding ‘ng-invalid’ class on ‘required’ fields

I am building an angular app for which I have some forms set up. I have some fields that are required to be filled before submission. Therefore I have added ‘required’ on them:

<input type="text" class="form-control" placeholder="Test" ng-model="data.test" required>

However when I launch my app, the fields are displayed as ‘invalid’ and the classes ‘ng-invalid’ and ‘ng-invalid-required’ even before the submit button has been click or before the user has typed anything in the fields.

How can I make sure that thoses 2 classes are not added immediately but either once the user has submitted the form or when he has typed something wrong in the corresponding field?

Answer

Since the inputs are empty and therefore invalid when instantiated, Angular correctly adds the ng-invalid class.

A CSS rule you might try:

input.ng-dirty.ng-invalid {
  color: red
}

Which basically states when the field has had something entered into it at some point since the page loaded and wasn’t reset to pristine by $scope.formName.setPristine(true) and something wasn’t yet entered and it’s invalid then the text turns red.

Other useful classes for Angular forms (see input for future reference )

ng-valid-maxlength – when ng-maxlength passes
ng-valid-minlength – when ng-minlength passes
ng-valid-pattern – when ng-pattern passes
ng-dirty – when the form has had something entered since the form loaded
ng-pristine – when the form input has had nothing inserted since loaded (or it was reset via setPristine(true) on the form)
ng-invalid – when any validation fails (required, minlength, custom ones, etc)

Likewise there is also ng-invalid-<name> for all these patterns and any custom ones created.

Categories
discuss

How to use Math.round to round numbers to the nearest EVEN number?

Using JavaScript only please.

This is the first time I am attempting to write JavaScript on my own. I’ve successfully manipulated codes that friends have written for me in the past, but I have never written my own from scratch, nor took the time to try and understand the language itself until recently.

I’m trying to make a basic bra size calculator that takes numbers (measurements) from user input, routes them into a function and returns (calculates) a bra size to the user.

Since I’m so new to this language, I’m only trying to write one part right now – “band size”

I have an input field for users to type in their “under bust measurement” which I currently have set to round. This works as it intended. See here

<html>

<head>

<script type="text/javascript">

 function calculate() 
  {
   var underbust = document.getElementById("underBust").value;

    if (underbust.length === 0) 
     {
      alert("Please enter your underbust measurement in inches");
      return;
     }

    document.getElementById("bandsize").innerHTML = Math.round(underbust);
   }

</script>

</head>

<body>
<input type="number" id="underBust" /> inches<br>
<input type="submit" value="Submit" onclick="calculate()" /><br>
<b>underbust:</b> <div id="bandsize">bandsize will appear here</div><br>
</body>

</html>

However, I don’t need the input ‘underBust’ to round to the nearest whole number. I need it to round to the nearest EVEN whole number, since bra band sizes only come in even whole numbers.

For example, if the user inputs the number “31.25” the code would currently round it to “31” but I need it to round it to “32”

If the user inputs the number “30.25” the code would round it correctly to “30” because the nearest whole number and nearest whole even number are the same in this case. However, if the user inputs “30.5” the code would round it up to “31” but I still need it to round down to “30”

Basically, I need the number to be rounded UP if the user input is equal to or greater than an odd number (29.00 becomes 30, 31.25 becomes 32, etc.). If the user input is greater than or equal to an even number and less than the next odd number (28, 28.25, 28.75, etc.) I need it to round down (in the previous example, to 28 for all cases). The odd number is the middle divide for rounding, instead of the “.5” of any number.

Is this possible?

Answer

This should do it:

2 * Math.round(underbust / 2);
Categories
discuss

Can you use a wildcard in getElementById?

I have the following line of code:

document.getElementById("question_*").setAttribute("disabled", "false");

I want to use a form of wildcard for the element ID. The script is run and used by lots of different buttons, they all have ID’s of question_something – is it possible to make this setAttribute to make the button enabled for various ID’s?

<button id="question_1a" onClick="nextQuestion(this.id)" disabled>Next question</button>

EDIT:

I’ve switched to a classname as suggested. Buttons now are:

<button id="question_1a" class="nextButton" disabled>Next question</button>

I’ve added the following line to make this not disabled:

var elems = document.getElementsByClassName('nextButton').setAttribute("disabled", "false");

But I get: Uncaught TypeError: Object # has no method ‘setAttribute’

Answer

You can’t use wildcards with document.getElementById(), you can, however, with document.querySelectorAll():

var elems = document.querySelectorAll('button[id^="question_"]');

This, of course, requires a relatively up to date browser; on the other hand using a class-name (for example question) to associate those elements would allow you to use:

var elems = document.getElementsByClassName('question');

Or:

var elems = document.querySelectorAll('button.question');

I tried doing this: var elems = document.getElementsByClassName('nextButton').setAttribute("disabled", "false"); – but I get: Uncaught TypeError: Object # has no method ‘setAttribute’

That’s because you can’t modify the properties of a NodeList all at once, you can, however, use a for (){...} loop, or similar to do so:

Using for(){...}:

var elems = document.getElementsByClassName('question');
for (var i = 0, len = elems.length; i < len; i++){
    elems[i].disabled = false; // to make them all enabled
}

JS Fiddle demo.

Or using forEach (up to date browsers):

var elems = document.getElementsByClassName('question');
[].forEach.call(elems, function(a){
    a.disabled = false; // will make all elements enabled
});

JS Fiddle demo.

References:

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..