Want the function to sort the table by HP but if duplicate HPs then sorts by name. When i run this function it just groups the duplicate HPs together in no order by the name.
T = { {Name = "Mark", HP = 54, Breed = "Ghost"}, {Name = "Stan", HP = 24, Breed = "Zombie"}, {Name = "Juli", HP = 100, Breed = "Human"}, { HP = 100, Breed = "Human"} }
function(x, y) if x.Name == nil or y.Name == nil then return x.HP < y.HP else return x.Name < y.Name and x.HP < y.HP end end) end
Try this sort func:
function(x,y)
if x.Name == nil or y.Name == nil then
return x.HP < y.HP
else
return x.HP < y.HP or (x.HP == y.HP and x.Name < y.Name)
end
end
Since you always want differing HPs to be the primary sorting order (and name secondary), you want the HP check to come first in the or clause so that if it differs it'll skip any other checks and just determine based on HP.
Related
I am working on this exercise in pil4.
Exercise 15.5:
The approach of avoiding constructors when saving tables with cycles is too radical. It is
possible to save the table in a more pleasant format using constructors for the simple case, and to use
assignments later only to fix sharing and loops. Reimplement the function save (Figure 15.3, “Saving
tables with cycles”) using this approach. Add to it all the goodies that you have implemented in the previous
exercises (indentation, record syntax, and list syntax).
I have tried this with the code below, but it seems not to work on the nested table with a string key.
local function basicSerialize(o)
-- number or string
return string.format("%q",o)
end
local function save(name,value,saved,indentation,isArray)
indentation = indentation or 0
saved = saved or {}
local t = type(value)
local space = string.rep(" ",indentation + 2)
local space2 = string.rep(" ",indentation + 4)
if not isArray then io.write(name," = ") end
if t == "number" or t == "string" or t == "boolean" or t == "nil" then
io.write(basicSerialize(value),"\n")
elseif t == "table" then
if saved[value] then
io.write(saved[value],"\n")
else
if #value > 0 then
if indentation > 0 then io.write(space) end
io.write("{\n")
end
local indexes = {}
for i = 1,#value do
if type(value[i]) ~= "table" then
io.write(space2)
io.write(basicSerialize(value[i]))
else
local fname = string.format("%s[%s]",name,i)
save(fname,value[i],saved,indentation + 2,true)
end
io.write(",\n")
indexes[i] = true
end
if #value > 0 then
if indentation > 0 then io.write(space) end
io.write("}\n")
else
io.write("{}\n")
end
saved[value] = name
for k,v in pairs(value) do
if not indexes[k] then
k = basicSerialize(k)
local fname = string.format("%s[%s]",name,k)
save(fname,v,saved,indentation + 2)
io.write("\n")
end
end
end
else
error("cannot save a " .. t)
end
end
local a = { 1,2,3, {"one","Two"} ,5, {4,b = 4,5,6} ,a = "ddd"}
local b = { k = a[4]}
local t = {}
save("a",a,t)
save("b",b,t)
print()
And I got the wrong ouput.
a = {
1,
2,
3,
{
"one",
"Two",
}
,
5,
{
4,
5,
6,
}
a[6]["b"] = 4
,
}
a["a"] = "ddd"
b = {}
b["k"] = a[4]
How could I make the text ' a[6]["b"] = 4 ' jump out of the table constructor?
Taking inspiration from this post:
How can I present a many-to-many relationship using a link table with ScalaQuery or SLICK?
My situation is a somewhat the same with some small exception.
def testManyToMany(): Unit = db withSession {
object A extends Table[(Int, String)]("a") {
def id = column[Int]("id", O.PrimaryKey)
def s = column[String]("s")
def * = id ~ s
def bs = AToB.filter(_.aId === id).flatMap(_.bFK)
// note I have another many-to-many join
def cs = AtoC.filter(_cId === id).flatMap(_.aFK)
}
object B extends Table[(Int, String)]("b") {
def id = column[Int]("id", O.PrimaryKey)
def s = column[String]("s")
def * = id ~ s
def as = AToB.filter(_.bId === id).flatMap(_.aFK)
}
object AToB extends Table[(Int, Int)]("a_to_b") {
def aId = column[Int]("a")
def bId = column[Int]("b")
def * = aId ~ bId
def aFK = foreignKey("a_fk", aId, A)(a => a.id)
def bFK = foreignKey("b_fk", bId, B)(b => b.id)
}
object AToC extends Table[(Int, Int)]("a_to_c") {
def aId = column[Int]("a")
def cId = column[Int]("c")
def * = aId ~ cId
def aFK = foreignKey("a_fk", aId, A)(a => a.id)
def cFK = foreignKey("c_fk", cId, C)(c => c.id)
}
}
Now when I want to fetch all A's by id, I would also want to fetch it associations in B and C, I would do something like:
for {
a <- A if a.id >= 2
aToB <- AToB if aToB.aId === a.id
b <- B if b.id === aToB.bId
} yield (a.s, b.s)
How can I include the join to the C table? Is having something like this correct?
for {
a <- A if a.id >= 2
aToB <- AToB if aToB.aId === a.id
aToC <- AToC if aToC.aId === a.id
b <- B if b.id === aToB.bId
c <- C if c.id === aToC.cId
} yield (a.s, b.s)
Wouldn't this try to do a sub-select on aToC for each aToB as this is just a flatMap operation?
I have a table:
employee = {
name = "John", age = 30,
name = "George", age = 35
}
Now, I want to run the whole table, and if the name "George" is found, then the appropriate age to be printed. How can I do this? From what I searched I found that you can run a list with the code for k, v in pairs(employee) do but I don't know how to continue from there.
Your table will need to be restructured to start off with.
employee = {
{name = "John", age = 30},
{name = "George", age = 35},
}
This will allow the age to always match up with the name. Then you could run:
for _,v in ipairs(employee) do
if v.name == "George" then
return v.age
end
end
You can even create it as a function so you can check whatever name you want:
function find_age(n)
for _,v in ipairs(employee) do
if v.name == n then
return v.age
end
end
end
Of course, this will return the age of every n in the table, though.
Updated for comment
You can do it with a function as well.
function add_employee(n,a)
table.insert(employee, {name = n, age = a})
end
I need my LINQ Query to return the Product Datatype, after being grouped. It seems to be encased into an anonymous psuedo family.
I have some properties in Product that I don't care about, just needing the p.ID and p.Name etc.
The error I'm getting at the moment with this is:
The entity or complex type 'DatabaseModel.Product' cannot be constructed in a LINQ to Entities query.
This is my Method:
public static List<Product> GetSellableSpecialOffers(DatabaseEntities db)
{
var query = from p in db.Products
where (p.Visible == true && p.Active == true)
&& p.ShowInSpecialOffers == true
group p by p.FamilyID == null ? 0 : p.FamilyID into f
select new Product {
ID = f.First().ID,
Name = f.First().Name,
Cost = f.First().Cost,
RRP = f.First().RRP
};
return query.ToList();
}
What is the problem? Is there a better way around this? SQL would always return 1 record instead of encasing the object in a secondary datatype, I don't get it.
Many thanks,
EDIT 1:
My apologies for extending the specification, but I need the returned product to be programatically generated e.g.
select new Product {
ID = f.First().ID,
Name = f.First().Name,
Cost = f.OrderBy(p => p.NowCost).FirstOrDefault(),
RRP = f.First().RRP
}
or if I could strongly type the family class:
public partial class ProductFamily
{
public Product GroupedProduct
{
get
{
return this.Products.OrderBy(p => p.NowCost).FirstOrDefault();
}
}
}
Then I would do:
var query = (from p in db.Products
where (p.Visible == true && p.Active == true)
&& p.ShowInSpecialOffers == true
group p by p.ProductFamily == null ? null : p.ProductFamily into f
select f.GroupedProduct).ToList<Product>();
But I can't get either solution to work with what I have.
You can try (boring, but not sure you have the choice)
var query = from p in db.Products
where (p.Visible == true && p.Active == true)
&& p.ShowInSpecialOffers == true
group p by p.FamilyID == null ? 0 : p.FamilyID into f
select new {
ID = f.First().ID,
Name = f.First().Name,
Cost = f.OrderBy(m => m.NowCost).First().Cost,
RRP = f.First().RRP
};
return query.ToList().Select(m =>
new Product {
ID = m.ID,
Name = m.Name,
Cost = m.Cost,
RRP = m.RRP
};
EDIT
Or as pointed by Master Skeet (not exactly the same as what you tried, but much easier)
var query = from p in db.Products
where (p.Visible == true && p.Active == true)
&& p.ShowInSpecialOffers == true
group p by p.FamilyID == null ? 0 : p.FamilyID into f
select f.OrderBy(m => m.NowCost).First();
You could simply select f.First() and return the resulting data, like this:
var query = from p in db.Products
where (p.Visible == true && p.Active == true)
&& p.ShowInSpecialOffers == true
group p by p.FamilyID == null ? 0 : p.FamilyID into f
select f.First();
Then outside the method use whatever properties you need, ignoring what you don't care about (you are handling Product objects, properties should be there even if you don't need them).
Remove the word 'Product' from
select new Product{}
'select new' itself will create an anonymous type whereas you are specifying it as a Product.
I am trying to sort but there is a nil. How can i get around this?
Code im useing: (sorting it by name and HPs. in case there is duplicate HPs)
T = { {Name = "Mark", HP = 54, Breed = "Ghost"},
{Name = "Stan", HP = 24, Breed = "Zombie"},
{Name = "Juli", HP = 100, Breed = "Human"},
{ HP = 100, Breed = "Human"}
}
function Sorting(T)
table.sort(T,
function(x,y)
return x.Name < y.Name and x.HP < y.HP
end
)
end
Assuming you want to compare by HP if name isn't available, how about you change the sort comparison function to:
function(x, y)
if x.Name == nil or y.Name == nil then return x.HP < y.HP
else return x.Name < y.Name and x.HP < y.HP
end
end
Your problem is that Name isn't a real key if it's not available all the time.