Single iteration = > multiple output sets from Java to Scala

I'm trying to convert some java code into Scala code The challenge is to ensure that the converted Scala code does not end up as inefficient as the original Java For example, when trying to convert the following code:

class Person {
    String name;
    Integer age;
    Character gender;
}

public class TestJava {
    public static void main(String[] args) {
        final List<Person> persons = new ArrayList<>();
        final List<Person> males = new ArrayList<>();
        final List<Person> aNames = new ArrayList<>();
        final List<Person> seniors = new ArrayList<>();
        for (final Person p: persons) {
            if (p.gender == 'm') {
                males.add(p);
            }
            if (p.age >= 60) {
                seniors.add(p);                
            }
            if (p.name.startsWith("a")) {
                aNames.add(p);
            }            
        }
    }
}

Because Java relies on mutation, the code looks logical But now I want to convert it to scala equivalent without multiple loops (in this case, three)

Of course, I can use the variable list in the scala library and do the same thing as Java, but I want to know whether I can generate multiple sets from a given sequence / set in a functional / Scala way without iterating the set time of N, where n is the standard count Thank you in advance!

Solution

A purely functional and immutable way is to have the general function of dividing a collection into buckets by predicates:

case class Person(name: String,age: Int,gender: String)

def bucketsByPredicate(people: Seq[Person],predicates: Seq[Person => Boolean]) = {
  people.foldLeft(predicates.map(predicate =>
    (predicate,List.empty[Person])
  )) { case (predicates,person) =>
      predicates.map { case (predicate,members) =>
        (predicate,if(predicate(person)) person :: members else members)
      }
  }.map(_._2)
}

An example might be:

val olderThan60 = (p: Person) => p.age >= 60
val male = (p: Person) => p.gender == "m"
val Seq(olderThan60People,malePeople) = bucketsByPredicate(people,Seq(olderThan60,male))
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
***
下一篇>>