Writing a Search Function

Hello,

I have a program that creates custom objects from text documents that contain certain pieces of data. Each object has its own Boolean tags that correspond to different states the object could be under based upon the data in the text file. A sample of the object would look something like this.

class Object {

String [] startingtext;

Boolean datastate1;
Boolean datastate2;
Boolean datastate3;

Object (String [] textfile){
startingtext = textfile;
}

}

When the program is finished there will be hundreds of different datastate Booleans possible for each object, each with unique names that correspond to different things I want to track about each object (aka, the Booleans will not have sequential names). A separate function runs that will read each object.textfile and activate the proper datastate Booleans to true. What I would like to be able to do is write a search function that would look something like the following pseudo code:

SomeSearchFunction(Object [] someobjectarray, Parameter adatastate){
//This code takes in an array of objects and searches for all objects where
//the Parameter variable is true.  The Parameter value can be any of the
//Boolean tags. This program would return an Object [] where all the chosen
//Parameter Boolean tags were true.
}

In short, I’m a little stumped on how best to accomplish this. Any ideas, examples, or tutorials that might speak to this would be very helpful.

Thank you.

If those tags are String names, maybe you should store them in a HashMap container: :hash:

import java.util.Map;
final Map<String, Boolean> tags = new HashMap<String, Boolean>();
3 Likes

Gotoloop is right

When you have a central hashmap with all booleans and all objects use this hashmap, then the search can for loop over it and compare a search pattern with the objects

On 2nd thought, given we’re simply checking whether an object contains some tag, we can just use a StringList instead: :bulb:
Processing.org/reference/StringList.html

And call its method hasValue() in order to check whether a String tag is stored in the container: :ticket:
Processing.org/reference/StringList_hasValue_.html

1 Like

I like @GoToLoop suggestion, but in this case maybe Java Set is even better thanks to containsAll method:

class MyObject {
  Set<String> tags = new HashSet<>();
  ...
}

MyObject[] search(MyObject[] objects, Set<String> tags) {
  List<MyObject> result = new LinkedList<>();
  for (MyObject object : objects) {
    if (object.tags.containsAll(tags)) {
      result.add(object);
    }
  }
  return result.toArray(new MyObject[0]);
}

It should be already quite fast thanks to hash functions, but if the performance is a concern, you might consider calling intern() on each string.

1 Like

The more idiomatic Java 8 way would be:

class MyObject {
  Set<String> tags = new HashSet<>();
}

MyObject[] search(MyObject[] objects, Set<String> tags) {
  return Stream.of(objects)
    .filter(myObject -> myObject.tags.containsAll(tags))
    .toArray(MyObject[]::new);
}

But I believe this one cannot be used in Processing directly due to lack of lambdas. Still it can be used when developing on top of Processing directly in Java, like I do in this project: https://github.com/morisil/processing-shaders/

Not only that, but even the empty <> diamond can’t be used inside “.pde” files, only in “.java” 1s! :frowning_face:

And lambdas aren’t allowed even in “.java” files under the Processing’s IDE (PDE)! :astonished:

Thanks for the suggestions everyone. I am still testing out my code but so far it looks like the first suggestion by GoToLoop works the way I want it to. I can add all the Boolean tags that an object might have into a HashMap by String name, then type that String name in as the parameter in the search function, if the parameter has a stored value in the HashMap then I can find out if that Boolean is true or false and run a for loop to cover each object.

That seems like it is doing exactly what I need. I haven’t tried any of the other methods but I will to see how each method functions.

1 Like