Initializing a 2-dimensions array in a domain class - grails

I am trying to represent a 16*16 grid in a domain class. Currently the grid is represented by a one-dimension array. This works:
class Grid {
List cells = []
static hasMany = [cells:Cell]
void init() {
// Initialize cells
for(int x = 0; x < 16*16 ; x++) {
addToCells(new Cell())
}
}
}
But what is the right way to create a two-dimensions array? Also, is there a way of initializing all the cells without iterating?

A domain class represents an entity that is mapped onto an underlying database table. I realized it had no point in storing a 2D array as such in a database.
As #Tim_Yates suggested in the comments, it's better to use the collate method. I've kept the 1D array as a property and can still access a proper 2D-representation of the grid using:
Cell[][] cellz = cells.collate(edgeSize)
Cell myCell = cellz[5][9]

Related

Assign matching column header from table with match criteria to a string list in an arrayformula in Google Sheets

In a Google Sheet I have a first tab with data entries in column A. I would like to assign a category to each entry in column B using an arrayformula. The category is supposed to be determined in the following way: If in the second tab one of the strings of a column matches the entry, the header of the column is supposed to be assigned as the category.
I have the feeling that there should be a way to do this with the query function, but can't figure it out.
This is an example sheet. I am happy to slightly change the setup of the sheet if the solution requires it but would like to avoid blowing up the sheet. Also I am interested in the simplest possible solution.
Approach
I would use a custom function in this case so that you can gain more control on the logic and structure of your sheet.
First you should change move the categories sheet into a rows structure since Google Sheets gets the values in that way.
Now let's build the function that extracts the data from the categories and assign every name to the corresponding one.
This is a custom function so I build the proper docs header so that it will be visible in your Spreadsheet context.
/**
* Assign the name the corresponding category.
*
* #param {input} the name to assign to the category
* #return The matching category
* #customfunction
*/
function MATCHCATEGORY(input) {
// if the input is from ARRAYFORMULA I will reiterate along the array with a map
if (input.map) {
return input.map(MATCHCATEGORY)
} else {
// Recursion base case
// I will get the categories rows
var rows = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CATEGORIES").getDataRange().getValues();
var category = "";
// Now I will map a string matching function along the rows
rows.map(row => {
let no_blanks = row.filter(value => value != "");
for (var i=1; i<no_blanks.length; i++) {
if (input.includes(row[i])) {
category = row[0];
break;
}
}
});
// Finally I return the category
return category
}
}
Now we can use our custom function inside an ARRAYFORMULA:
=ARRAYFORMULA(MATCHCATEGORY("ENTRY COLUMN RANGE"))

Can you specify a List<T> with specific length as a type

Let's assume we are designing a sudoku model which takes 9 Tile3x3 objects as a list. How would I explicitly specify the length of List so that it can only have 9 objects of Tile3x3s.
class Sudoku {
List<Tile3x3> tiles3x3;
}
You can create a fixed length list in Dart like so:
class Sudoku {
final var tiles3x3 = List<Tile3x3>(9);
}
tiles3x3 will not support adding or changing the length of the List.

Group TableView items from NSArray returned in JSON Response in Swift

I have a table view and I want to populate the table view with the values provided to me in a JSON response in the form of NSArray and I have used the code below to extract this NSArray:
dispatch_async(dispatch_get_main_queue(), {
print(json)
if let listDictionary = parseJSON["list"] as? NSArray {
print("LIST: \(listDictionary)")
}
})
In JSON response, I get the following array of two elements as shown below:
list = (
{
"is_cover" = 0;
"is_recommand" = 0;
name = "Helena's Signature Dish";
ord = 5;
price = "105.00";
remark = "Helena's special made dish is one of the most priced and delicious dishes in the whole world.";
thumb = "56c351887a0e0.jpg";
},
{
"is_cover" = 0;
"is_recommand" = 0;
name = "Pineapple Fried Rice";
ord = 6;
price = "110.00";
remark = "We have the most delicious pineapple rice in the whole world!";
thumb = "56c704e15da79.jpg";
}
);
Now I want to show the value "name", "price" and "remark" fields from each element in the array into a UITableView.
But I can't find a way to break the values for name, price and remark for each element and put them into an another array so they can be displayed in a table view somehow because each element contains a very long string and I only need to extract some values from this string. Can anyone please help me with this as I'm very new to Swift.
Thanks!
You don't need to make a second array, Only extarct particular json from array in cellForRowatIndexPath on dictinary by objectatindex method of array and now you can access.
You can achieve it by creating a model Class which contains only
those properties which you needed.
Once you get the response array from server , iterate though each
dictionary and create a Model Object.Add this model objects in the
Array.
Use this model object in the Array for applying data in your cell using the index
One more thing to add is always prefer using objects as it gives (.)dot syntax & autosuggestion, so there will be less chances of
making mistakes. As if you use Dictionary there will be more chances
of using incorrect key getting crash
I fixed this by putting values in "name", "price" and "remark" fields into another array using flatMap as shown below:
let nameArray = listArray.flatMap({ element in (element["name"] as? String)! })
And then I got something like:
Name's: (
"Helena's Special Dish",
"Pineapple Fried Rice"
)
and then in the tableView function for cellForRowAtIndexPath I grouped the values in tableview.

Receiving array in route data to be used in Where func + MVC

I am receiving an array in route data containing different string values. Since I don't know how many string values I am going to receive, I cant have a definite Where function. Hence I am looping through the array and making multiple calls to DB set, fetching the result and adding it into another Master List. Please see code below.
public JsonResult GetModels(string brand)
{
string[] brands = brand.Split(seperator);
MasterList.Clear();
for (int i = 0; i < brands.Length; i++)
{
tempString = brands[i];
tempList = db.Devices.Where(r => r.Brand.Equals(tempString)).Select(r => new MySelectList { Value = r.PhoneModel, Text = r.PhoneModel }).Distinct().ToList();
for (int a = 0; a < tempList.Count; a++)
MasterList.Add(tempList[a]);
}
return Json(MasterList, JsonRequestBehavior.AllowGet);
}
Is there a way I can somehow avoid looping through the array and use it directly in Where function? Meaning Where function can look into values of the array and return result based on it.
You can do this by using Contains. This effectively generates an SQL IN clause:
tempList = db.Devices.Where(r => brands.Contains(r.Brand));

Fastest way to check Map for duplicate values?

Given a Map, assignment, what is the fastest way to check if it contains any duplicate values in Dart? I am currently using a Set formed from the Map's values and checking its length against the original Map, which works of course, but I'm wondering if there's an especially performant alternative.
Set d = new Set.from(assignment.values);
if (d.length < assignment.length) {
return false; // indicates has duplicates in this context
}
EDIT:
Tried #mezoni's solution modified for my program, but it actually ran a bit slower than my original version. It probably has more to do with constant times than anything else.
List values = new List.from(assignment.values);
Set set = new Set();
for (var i = 0; i < assignment.length; i++) {
if (!set.add(values[i])) {
return false;
}
}
Complexity wise you won't be able to get anything faster. Creating the Set and filling it with the values of the Map is linear in the number of elements. Clearly you have to run through all the values, so you can't do any better than that.
Maybe you could find a solution with a smaller constant factor, but that's not clear. In particular for larger sets I think the Set solution is pretty efficient.
This is more of a algorithms question than a Dart question. In any case, you have to check every value against the others, giving n-1 + n-2 + ... + n-(n-1) checks, or n^2/2. Programmatically, it's easy to create a set, but you could also generate an array, sort the array, and then iterate once to check for duplicates. That finishes in O(n log n).
Fastets way (if you realy need better performance):
void main() {
// Values from map
var values = [1,2,3,2,1,3,2,1];
var length = values.length;
var set = new Set();
var duplicate = false;
// Only for statistics purpose
var statistics = 0;
for(var i = 0; i < length; i++) {
statistics++;
if(!set.add(values[i])) {
duplicate = true;
break;
}
}
print("Duplicate: $duplicate");
print("Performed in ${statistics} iteration(s) from $length possible");
}
Output:
Duplicate: true
Performed in 4 iteration(s) from 8 possible
P.S.
The first example can be recommended to use with List values.
But because Map.values not a List but Iterable then it would be more efficient do not convert them to List but use as is.
Here is modified sample for use with Iterable objects.
It will be work faster because in this algorithm not required convert all values to the List object because it not want using of all elements without exception.
Instead it wants use as less as possible access operation on original source. If the source supports lazy operation of the access to values (as Iterable) this will be even better.
void main() {
// Values from map
var values = [1,2,3,2,1,3,2,1];
var assignment = {};
var length = values.length;
var key = 0;
for(var value in values) {
assignment[key++] = value;
}
var set = new Set();
var duplicate = false;
// Only for statistics purpose
var statistics = 0;
for(var value in assignment.values) {
statistics++;
if(!set.add(value)) {
duplicate = true;
break;
}
}
print("Duplicate: $duplicate");
print("Performed in ${statistics} iteration(s) from $length possible");
}

Resources