Groovy is extremely powerful managing collections. I have a list like this one:
def nameList = ["Jon", "Mike", "Alexia"]
What I am trying to do is iterating 10 times to get ten people with a random name from the first list.
10.times{
Person person = new Person(
name: nameList.get() //I WANT TO GET A RANDOM NAME FROM THE LIST
)
}
This is not working for two obvious reasons, I am not adding any index in my nameList.get and I am not creating 10 different Person objects.
How can I get a random element from my name list using groovy?
Can I create a list with 10 people with random names (in a simple way), using groovy's collections properties?
Just use the Java method Collections.shuffle() like
class Person {
def name
}
def nameList = ["Jon", "Mike", "Alexia"]
10.times {
Collections.shuffle nameList
Person person = new Person(
name: nameList.first()
)
println person.name
}
or use a random index like
class Person {
def name
}
def nameList = ["Jon", "Mike", "Alexia"]
def nameListSize = nameList.size()
def r = new Random()
10.times {
Person person = new Person(
name: nameList.get(r.nextInt(nameListSize))
)
println person.name
}
Related
i want to filter a list of student in java. I have a student class in kotlin like this.
class Student(
var id: String? = null,
var firstName: String? = null,
var lastName: String? = null
) {
constructor(entity: StudentCourse?): this() {
if (entity != null) {
this.id = entity.id.id
this.name = entity.name
}
}
}
class StudentCourse (#EmbeddedId open var id: StudentCourseId) {
constructor() : this(StudentCourseId())
open var name: Boolean? = null
}
#Embeddable
open class StudentCourseId: Serializable {
open var id: String? = null
open var deptName: String? = null
}
this is the list i want to filter :
var students: List<Student> = listOf(
Student("14adbv45", "dan", "GEG"),
Student("96adbv42","Bob", "Bowyer"),
Student("30adbv45","Emily", "Eden")
)
I do this
List<students> studentListContainsFirstNameBob = students.stream()
.map(StudentCourse)
.filter(e -> e.getFirstName.equals("Bob"))
.flatMap(List::stream);
but it doesn't work.
How can i do it please
There are multiple issues in your code.
For example in this part:
constructor(entity: StudentCourse?): this() {
if (entity != null) {
this.id = entity.id.id
this.name = entity.name
}
}
The entity.name refers to StudentCourse#name, but this property is actually of Boolean type, so comparing it to String doe snot make much sense. You have also doubled .id which is incorrect.
Next thing, I am not sure what this snipped should do, was the intention to link a student with given course? If so, you would probably like to add a list of students to a course, or a list of courses to a student (which sounds more correct).
Finally, when it comes to filtering a list, you can get students with first name Bob in this way:
var studentListContainsFirstNameBob: List<Student> = students
.filter { it.firstName.equals("Bob") }
.toList()
Mind the it variable refers to the element from the list, it could also be written:
var studentListContainsFirstNameBob: List<Student> = students
.filter { student -> student.firstName.equals("Bob") }
.toList()
I'm trying to put some objects in a mutableListOf, but all of them ended up overriding.
class Users {...}
class dbUsers{
var users = Users()
val list = mutableListOf(users)
fun addUser(phone: Int, name: String){
users.phone = phone
users.name = name
list.add(users)
}
}
fun main() {
var dbAccess = dbUsers()
dbAccess.addUser(8439, "Thiago")
dbAccess.addUser(12312, "Maria")
println(dbAccess.list[0].name)
println(dbAccess.list[1].name)
}
When We print at position 1, we see that was override
You have initialized Users object only once, at the class level in dbUsers. You need to create new object everytime before adding the user to the list. Move the users initialization within the method instead
class dbUsers{
val list = mutableListOf<Users>()
fun addUser(phone: Int, name: String){
var users = Users()
users.phone = phone
users.name = name
list.add(users)
}
}
It looks like the list is referencing from users and since users itself is updated every time, you get this results.
There are two ways you can approach this issue ,
Creating a new user every-time calling addUser , this is easy
If you have other data in Users than name and phone , you can just make a DeepCopy of your object by add in a new function in your class copy() like
class YourClass () {
// Your class other stuffs here
fun copy(): YourClass { //Get another instance of YourClass with the values like this!
val json = Gson().toJson(this)
return Gson().fromJson(json, YourClass::class.java)
}
}
then by using yourClassObject.copy() you will get a new instance with same values
fun addUser(phone: Int, name: String){
val newUsers = users.copy()
newUsers.phone = phone
newUsers.name = name
list.add(newUsers)
}
I have a list of model class objects. Such as -
List<ModelChannel> allChannels = [];
I have added elements in this list from json. Model Class variables are-
final String channelid;
final String channelname;
final String channeltype;
final String categoryname;
final String channelimage;
final String channelurl;
Here categorytype contains country information. I want to divide the list country wise dynamically. I have intended to use 2d list where each row will contain all the channels of a specific country. Is this the right approach? If yes how to implement this and if not what will be the right one?
If I understand correctly, you are looking for groupBy function from collection package.
Add this package to your pubspec.yaml:
dependencies:
collection: any
And use groupBy:
import 'package:collection/collection.dart';
...
final groupByCountry = groupBy(allChannels, (ModelChannel e) => e.categoryname);
List<List<ModelChannel>> countryList = [];
List<String> channelType = [];
allChannels.forEach((element) {
if (channelType.isEmpty) {
channelType.add(element.channeltype);
} else {
if (channelType.contains(element.channeltype)) {
} else {
channelType.add(element.channeltype);
}
}
});
channelType.forEach((countryCode) {
List<ModelChannel> t = [];
allChannels.forEach((element) {
if (element.channeltype == countryCode) {
t.add(element);
}
});
countryList.add(t);
});
For some reason, I can't figure out how to simply find a specific piece of data in my SQLAlchemy database.
In the graphene-python documentation it simply does this query to match the id (which is a string):
book(id: "Qm9vazow") {
id
title
}
Now here's my Flask-Graphene-SQLAlchemy code for my BookSchema and I want to find a specific title instead of an ID:
class BookModel(db.Model):
__table__ = db.Model.metadata.tables['books_book']
# Schema Object
class BookSchema(SQLAlchemyObjectType):
class Meta:
model = BookModel
interfaces = (relay.Node, )
# Connection
class BookConnection(relay.Connection):
class Meta:
node = BookSchema
# GraphQL query
class Query(graphene.ObjectType):
node = relay.Node.Field()
allBooks = SQLAlchemyConnectionField(BookConnection)
schema = graphene.Schema(query=Query, types=[BookSchema])
When I run this query, everything is fine and returns 3 book titles:
{
"query": "{ allBooks(first: 3) { edges { node { title } } } }"
}
However, once I try to match a specific title, it stops working. For example:
# I tried all these queries, none worked
1. { allBooks(title: \"some book title\") { edges { node { title } } } }
2. { allBooks(title: \"some book title\") { title }
3. { allBooks(title: 'some book title') { edges { node { title } } } }
The error: "Unknown argument \"title\" on field \"allBooks\" of type \"Query\"."
I must be making a small error that I'm not seeing, but I can't figure it out. I've spent hours trying to figure this out.
Question: How can I match the title and have it return the object? What am I doing wrong?
Figured it out! See changes below.
class Query(graphene.ObjectType):
node = relay.Node.Field()
all_books = SQLAlchemyConnectionField(BookConnection)
# Added this
find_book = graphene.Field(BookSchema, title = graphene.String())
def resolve_find_book(self, info, title):
query = BookSchema.get_query(info)
return query.filter(BookModel.title == title).first()
And my GraphQL query looks like this:
{
"query": "{ findBook(title: \"some book title\") { title } }"
}
Hope this helps someone in the future!
I have a small Groovy Class called "zzz". The purpose of this class is to first demonstrate successfully passing a binding to the template engine producing an output and then failing to bind to another template engine using what appears to be the same set of bindings.
V1.template contains the base message that will be used with the bindings to produce a final output. V1.properties contains an XPath expression that should grab the value from an XML document and add it to the bindings. T1.xml is the raw xml input file.
In the zzz Groovy Class I have hard coded the LastName in bindings1 and that works. But, when I grab the lastName value from the XML file and add it to bindings2 it fails. Both bindings appear to have exactly the same text, but I have noticed that bindings1 is of type Bindings and binding2 is of type Reference.
I assume that bindings2 being of Reference is what is causing my problem, but I don't know how to cast or convert it to Binding. Please let me know what I'm doing wrong.
I'm using Java 1.8 with groovy-all-2.3.10.jar
zzz.groovy:
import java.io.File;
import javax.xml.xpath.*
import javax.xml.parsers.DocumentBuilderFactory
class zzz {
def xpath
def records
def loadDocToCheck(File docToCheck) {
xpath = XPathFactory.newInstance().newXPath()
def builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
def inputStream = new FileInputStream( docToCheck )
records = builder.parse(inputStream).documentElement
}
def validateXpath(String xpathQuery ) {
def nodes = xpath.evaluate( xpathQuery, records, XPathConstants.NODESET )
nodes.collect { node -> node.textContent }
def nodeCount = 0
nodes.each { nodeCount++ }
nodeCount
}
def getXpath(String xpathQuery ) {
String retVal = ""
def nodes = xpath.evaluate( xpathQuery, records, XPathConstants.NODESET )
nodes.collect { node ->
retVal += node.getTextContent()
}
(retVal)
}
static main(args) {
def zzz = new zzz()
def testFile = new File("T1.xml")
zzz.loadDocToCheck(testFile)
def config = new ConfigSlurper().parse(new File("V1.properties").toURI().toURL())
String testFileNameOnly = testFile.getName()-testFile.getParent()
def bindings1 = [
"InputFile" : "$testFileNameOnly",
"LastName" : "Smith"
]
def templateFile1 = new File('V1.template')
println "templateFile1=${templateFile1.getAbsolutePath()}"
def engine1 = new groovy.text.GStringTemplateEngine()
def template1 = engine1.createTemplate(templateFile1).make(bindings1)
println template1.toString()
println "******************************"
def bindings2 = [:]
bindings2 << ["InputFile":"$testFileNameOnly"]
config.params.each { paramName, param ->
bindings2 << ["$paramName" : "${zzz.getXpath(param)}"]
}
println "bindings2=$bindings2"
def templateFile2 = new File('V1.template')
println "templateFile=${templateFile2.getAbsolutePath()}"
def engine2 = new groovy.text.GStringTemplateEngine()
def template2 = engine2.createTemplate(templateFile2).make(bindings2)
println template2.toString()
}
}
T1.xml:
<?xml version="1.0"?>
<MyRoot specVersion="3.03">
<employee>
<lastName>Smith</lastName>
<firstName>John</firstName>
</employee>
</MyRoot>
V1.template:
Input file: ${InputFile}
LastName: ${LastName}
V1.properties:
params {
LastName = '//MyRoot/employee/lastName/text()'
}
I found why the second template would could execute. The bindings must be in the form of Map, but I was passing in a GString as the key for the map. Note: "$parameterName" is a GString. After converting the key to a String the second template executed correctly.