Grails giving sorted list to findAllByIdInList - java

I dont want the result re-sorted.
Example:
def ids = [7, 9, 5, 6, 12, 2, 10, 1, 42, 13]
result = Project.findAllByIdInList(ids).collect{
projectUtil.createProjectDTO(it)
}
Then if I get the Ids of object created they are sorted this way
result = [1, 2, 5, 6, 7, 9, 10, 12, 13, 42]
I'd like to keep the same order is there a way to achieve that ?
Thanks in advance and sorry for my bad english :)

You could try using getAll instead of findAllByIdInList:
def ids = [7, 9, 5, 6, 12, 2, 10, 1, 42, 13]
result = Project.getAll(ids).collect {
projectUtil.createProjectDTO(it)
}
I just tested it with a similar example in an integration test and it returned the instances in the same order as declared in the list of IDs.

Another option is withCriteria
result = Project.withCriteria {
'in'('id', ids)
}.collect { projectUtil.createProjectDTO(it) }

Related

How does comparator works internally?

It may sound trivial for you but I am having a hard time visualizing the comparator / array.sort. How can we sort a full array using only 2 arguments? How does it work internally?
for example- Input -[5,3,2,6,8,10,1], Output- [1,2,3,5,6,8,10]
Which algo does it use internally? Which 2 objects does it compare at first? (5 compared to 3?) and then what are the next two objects? (5 compared to 2?) or (3 compared to 2)?
public static void main(String[] args) {
Integer[] tring = new Integer[]{5,3,2,6,8,10,1};
lol(tring);
for(int i=0;i<tring.length;i++){
System.out.println(tring[i]);
}
}
public static void lol(Integer[] args) {
Arrays.sort(args,(h1,h2)->h1-h2);
}
You can visualize the process like this.
Integer[] tring = new Integer[] {5, 3, 2, 6, 8, 10, 1};
Comparator<Integer> comparator = (a, b) -> {
System.out.println(Arrays.toString(tring) + " comparing " + a + " and " + b);
return a.compareTo(b);
};
Arrays.sort(tring, comparator);
System.out.println(Arrays.toString(tring));
result:
[5, 3, 2, 6, 8, 10, 1] comparing 3 and 5
[5, 3, 2, 6, 8, 10, 1] comparing 2 and 3
[5, 3, 2, 6, 8, 10, 1] comparing 6 and 2
[2, 3, 5, 6, 8, 10, 1] comparing 6 and 3
[2, 3, 5, 6, 8, 10, 1] comparing 6 and 5
[2, 3, 5, 6, 8, 10, 1] comparing 8 and 5
[2, 3, 5, 6, 8, 10, 1] comparing 8 and 6
[2, 3, 5, 6, 8, 10, 1] comparing 10 and 5
[2, 3, 5, 6, 8, 10, 1] comparing 10 and 8
[2, 3, 5, 6, 8, 10, 1] comparing 1 and 6
[2, 3, 5, 6, 8, 10, 1] comparing 1 and 3
[2, 3, 5, 6, 8, 10, 1] comparing 1 and 2
[1, 2, 3, 5, 6, 8, 10]
The comparator uses a sort called a TimSort
I personally do not feel qualified to explain the timsort algorithm, but I'm sure you can find plenty of explanations on google.
For the second part of your question, the way the comparator uses your two augments is to determine what order any two given values order should be.
So, for example, say if you wanted to sort [6,4] the comparator would use your function a-b and would then plug in the numbers 6 and 4 and get the 2 and because 2 is positive the sort knows that 6 needs to be behind 4. Which would result in [4,6].

Java ArrayList.removeAll()

I want to make a section of code that takes a list of lists, splits it into sublists of 9 and remove numbers from all the lists in each of the sublists. However, when my code runs it removes numbers from all the lists, not just the section taken from the original list
for (int startingIndex = 0; startingIndex <= 8; startingIndex++) {
int initialIndex = startingIndex * 9;
ArrayList<ArrayList<String>> gridRow = new ArrayList<ArrayList<String>>();
gridRow.addAll((posabilityGrid.subList(initialIndex, initialIndex+9)));
System.out.println("gridrow - " + gridRow);
ArrayList<String> numbers = new ArrayList<String>();
for (ArrayList<String> posability : gridRow) {
if (posability.size() == 1) {
numbers.add(posability.get(0));
}
}
System.out.println("numbers - " + numbers);
for (ArrayList<String> posability : gridRow) {
posability.removeAll(numbers);
}
System.out.println("newgrid - " + gridRow);
edit:
When the starting index first equals 0:
grid row - [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [4], [3], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [2], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9]]
numbers - [4, 3, 2, 9]
it then correctly prints out:
newgrid - [[1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [], [], [1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [], [1, 5, 6, 7, 8], []]
However, when starting index equals 1 at the start:
gridrow - [[1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [5], [1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [9], [1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [1]]
instead of the expected
[[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [5], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1]]
This section of the list has had the previous numbers removed from it for some reason when it should stay the same so the only the new set of numbers are subtracted
2nd edit:
I've added the line
numbers.clear();
but i still have the same problem.
I've printed out the numbers list and checked that it is cleared each time but the main list seems to be changed on the first "posability.removeAll(numbers);"
Edit 3:
I've solved it now, The problem was with the ArrayList and Sublists. Once I changed the list so a new ArrayList deepcopy is created rather then just referencing the old one the code works great.
List<List<String>> posabilityGridClone = posabilityGrid.stream().map(it -> new ArrayList(it)).collect(Collectors.toList());
gridRow.addAll((Collection<? extends ArrayList<String>>) (posabilityGridClone.subList(initialIndex, initialIndex+9)));
Add numbers.clear() as the last line of your main cycle. You numbers array is persisted between cycles and it is the problem if I correctly understand what you expect to get.
EDIT
Sorry, I didn't saw numbers at first. I though it was created out of scope.
You problem is actually in this line:
gridRow.addAll((posabilityGrid.subList(initialIndex, initialIndex+9)));
When you create a sublist you have two problems here:
1) Sublist is just a view of the same array. (removing element from sublist affect original list)
2) Elements of array are references to another arrays. So when you run removeAll you actually remove it all from original arrays.
What you need is to make deepcopy of you arrays of arrays and use it instead of original one.
List<List<String>> posabilityGridClone = posabilityGrid.stream().map(it -> new ArrayList(it)).collect(Collectors.toList());
gridRow.addAll((posabilityGridClone.subList(initialIndex, initialIndex+9)));

Java & Mongodb -- how to update where not in array

this array = [1,2,3,4,5,6,7,8,9,10]
{
"number" : 11,
...
},
{
"number" : 9,
...
},
{
"number" : 3,
...
},
{
"number" : 20,
...
},
{
"number" : 5,
...
},
{
"number" : 7,
...
}
I want to update number : 11 20
I did not find documentation on this.
I think I know what this question is supposed to ask. It seems like I've misinterpreted it "earlier".
You have an array stored in mongodb like that:
{ "_id" : ObjectId("..."), "test" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] }
You have another array somewhere within your program:
[11, 9, 3, 20, 5, 7]
And you want to update the array stored in mongodb adding only values that do not exist there yet(uniquely).
If that is the question here is the answer:
How to do do that in the console:
db.yourdb.updateOne({ _id: ObjectId("...")}, {$addToSet: {"test": {$each: [20, 11]}}})
$addToSet ensures that it is added only once and $each will prevent that an array is added instead like that: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, [20, 11]].
In Java:
I'm not familiar with the Java driver, but it should go something like this:
coll.updateOne(Filters.eq("_id", "..."), new Document("$addToSet", new Document("test", new Document("$each", [11, 9, 3, 20, 5, 7]))));

Understanding indices in OpenGL ES 2.0

I know there are a lot of questions regarding indices, but none of them solve my problem. I am trying to get a model loaded with diffuse light source into openGl ES and rotate it. I first started with a 3D cube and managed to rotate it. Then i added a light source. That also went without a glitch. Now i'm trying to load a model from it's .obj file and rotate it in place of the cube. I tried two .obj converters but it didn't do the trick for me. Then i created my own .obj importer and the result was the same. I get a distorted image (the lighting and rotation still work on the distorted model). Now i feel that my knowledge about indices might be incomplete.
What I am doing is i am creating a vertexPositionArray[] to store the vertex information and a vertexNormalArray[] to store the corresponding normals with a 1:1 ratio. Now i create an indexArray which stores the order in which the position and the normals should be called.
For eg. if i pass in 3, 5, 6, I am referring to the 3rd, 5th, 6th positions in the vertexPositionArray[] and vertexNormalArray[] both or just the vertexPositionArray?
This is a model that i want to use in my project, and on the sides are the output i am getting
Here is a piece of code that i used to extract the info i wanted from .obj file:
String[] vData={"-1.000000f, 0.000000f, 1.000000f,",
"1.000000f, 0.000000f, 1.000000f,",
"-1.000000f, 0.000000f, -1.000000f,",
"1.000000f, 0.000000f, -1.000000f,",
"0.513184f, 0.000000f, 0.513184f,",
"0.513184f, 0.000000f, -0.513184f,",
"-0.513184f, 0.000000f, -0.513184f,",
"-0.513184f, 0.000000f, 0.513184f,",
"0.158195f, 0.690612f, 0.158195f,",
"0.158195f, 0.690612f, -0.158195f,",
"-0.158195f, 0.690612f, -0.158195f,",
"-0.158195f, 0.690612f, 0.158195f,"};
String[] nData={"-0.889400f, 0.457200f, 0.000000f,",
"0.000000f, -1.000000f, 0.000000f,",
"0.000000f, 1.000000f, 0.000000f,",
"0.889400f, 0.457200f, 0.000000f,",
"0.000000f, 0.457200f, 0.889400f,",
"0.000000f, 0.457200f, -0.889400f,"};
int[] vOrder={8, 12, 11,
6, 5, 3,
7, 6, 1,
8, 7, 2,
5, 8, 4,
11, 12, 9,
6, 10, 9,
5, 9, 12,
7, 11, 10,
7, 8, 11,
1, 6, 3,
2, 7, 1,
4, 8, 2,
3, 5, 4,
10, 11, 9,
5, 6, 9,
8, 5, 12,
6, 7, 10};
int[] nOrder={ 1, 1, 1,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
3, 3, 3,
4, 4, 4,
5, 5, 5,
6, 6, 6,
1, 1, 1,
3, 3, 3,
3, 3, 3,
3, 3, 3,
3, 3, 3,
3, 3, 3,
4, 4, 4,
5, 5, 5,
6, 6, 6,
};
FileWriter write = new FileWriter( path , false);
PrintWriter print_line = new PrintWriter( write );
print_line.println("float[] vertexData ={");
for(int i=0;i<vOrder.length;i++)
{
print_line.println(vData[vOrder[i]-1]);
vCount++;
}
print_line.println("};");
print_line.println("float[] vertexNormal ={");
for(int i=0;i<nOrder.length;i++)
{
print_line.println(nData[nOrder[i]-1]);
}
print_line.println("};");
print_line.println("Vertex Count = "+vCount);
print_line.close();
}
}
I got vData (vertex) and nData (normals) from the obj file by using the replace function in a text editor. Similarly i got the vOrder and nOrder by the data on the faces given below (Adding the number before'//' to vOrder and the one after to nOrder):
f 8//1 12//1 11//1
f 6//2 5//2 3//2
f 7//2 6//2 1//2
f 8//2 7//2 2//2
f 5//2 8//2 4//2
f 11//3 12//3 9//3
f 6//4 10//4 9//4
f 5//5 9//5 12//5
f 7//6 11//6 10//6
f 7//1 8//1 11//1
f 1//3 6//3 3//3
f 2//3 7//3 1//3
f 4//3 8//3 2//3
f 3//3 5//3 4//3
f 10//3 11//3 9//3
f 5//4 6//4 9//4
f 8//5 5//5 12//5
f 6//6 7//6 10//6
Could anyone please tell me what is it I'm doing wrong here?
Thanks in advance. Any help would be appreciated.
if i pass in 3, 5, 6, I am referring to the 3rd, 5th, 6th positions in the vertexPositionArray[] and vertexNormalArray[] both or just the vertexPositionArray?
Both
Do i need to bind my position and normal arrays into 1 array?
No, but you can, not required.
tell me if i understand the .obj file correctly:- f 8//1 5//4 6//3 for this i pushed the vertexPositionArray[7] and vertexNormalArray[0] into a new vertexPArray[] and vertexNArray[], respectively.
Yes, because Obj files're not related to OpenGL at all.
In OpenGL, you can have only one indices array but OBJ files, you can have three types of inces (f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ....) so you should create your new vertexPArray[] and vertexNArray[] using the faces data.

Passing a vector of integers to two separate functions but altered data gets passed to the other functions

*Update: Resolved did a deep copy, thanks for the help
I am using a vector of integers to simulate some sorting algorithms, when i insert numbers to the test vector and shuffle the order and pass it to a sorting function, if i pass the void sorting functions the same vector, when the vector gets sorted in a function previously passed the newly sorted vector gets passed to the function following it because it is already sorted i cannot show the sorting process. For example in my following code
#SuppressWarnings("unchecked") // Removes error given at when adding elems to int_vec
public static void CreateVec (int array_len)
{
Vector <Integer> int_vec = new Vector(array_len);
int temp_int = 1;
int low_bound = 0;
int high_bound = array_len - 1;
for(int i = 0; i<array_len; i++)
{
int_vec.addElement(temp_int);// creating a vec in respect to array len
temp_int ++;
}
Collections.shuffle(int_vec);
System.out.println("OG vec: " + int_vec); //original vector (random order)
BubbleSort(int_vec,array_len); //sending int_vec to bubble sort
InsertionSort(int_vec,array_len); // retrieves newly sorted vector sorted from BubbleSort (problem)
}
So my question follows, how can i keep sending my test vector (int_vec) with the randomly ordered elements rather than it keep sending the sorted vector to the other algorithms. Note i correctly implemented these algorithms, it works if i comment out the function calls to the other algorithm functions.
Create a copy of int_vec with new Vector<Integer>(int_vec) and pass in the copy to your sorting methods. This way, only the copy will get sorted, and int_vec will still be randomly ordered, and ready to be copied again for the next sorting method.
And yes, this is a shallow copy, but a deep copy is not needed here.
it doesnt seem to be working i did the following
Vector <Integer> int_vec = new Vector(array_len);
Vector <Integer> copy_bub = new Vector <Integer> (int_vec);
//...//
BubbleSort(int_vec,array_len);
InsertionSort(copy_bub,array_len);
and this is the output
Output:
OG vec: [4, 8, 9, 6, 10, 2, 1, 5, 3, 7]
Copy vec: [4, 8, 9, 6, 10, 2, 1, 5, 3, 7]
Bubble Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Insertion Vec: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Categories