In Lua, how do I insert a new column on a table like the one below?
table t = {
{name = "John", age = 19, sex = "M"},
{name = "Susan", age = 20, sex = "F"},
{name = "Paul", age = 18, sex = "M"}
}
I want to put a column id before the name, so the table could be like this:
table t = {
{id = 1, name = "John", age = 19, sex = "M"},
{id = 2, name = "Susan", age = 20, sex = "F"},
{id = 3, name = "Paul", age = 18, sex = "M"}
}
PS: the data of this table is coming from a file like the one below:
entry {name = "John", age = 19, sex = "M"}
entry {name = "Susan", age = 20, sex = "F"}
entry {name = "Paul", age = 18, sex = "M"}
and I'm using this code to insert this data into the table:
data = {}
text = file:read()
do
function entry(entrydata)
table.insert(data, entrydata)
end
thunk = load(text, nil, nil, {entry = entry})
thunk()
end
for i,v in ipairs(t) do
v.id=i
end
Alternately, you could set the value during loading:
data = {}
text = file:read()
do
local index=1
function entry(entrydata)
entrydata.id=index
index=index+1
table.insert(data, entrydata)
end
thunk = load(text, nil, nil, {entry = entry})
thunk()
end
Related
I have a list that looks like this.
-100 Smith, Jane $1000
-100 Smith, John $1100.00
-100 Smith, Cole $840.00
-110 Jones, Harry $1270.00
-110 Jones, Diane $870.00
-111 Jones, Richard $1560.00
Using LINQ, I wish to write a query that will allow me to SUM up the values by family.
The first identifier is the family id.
For the above set of records, my output will look like:
-100 Smith $2940.00
-110 Jones $2140.00
-111 Jones $1560.00
Here's my code:
static void Main(string[] args)
{
_fi = FillIncome();
var query = (from f in _fi group f by f.familyId into delta select new {familyId = delta.Key, amount = delta.Sum(x => x.income) });
foreach (var q in query)
{
Console.WriteLine(q);
}}
static List<FamilyIncome> FillIncome()
{
var income = new List<FamilyIncome>();
var fi = new FamilyIncome {familyId = -100, lastname = "Smith", firstname = "Jane", income = 1000};
income.Add(fi);
fi = new FamilyIncome { familyId = -100, lastname = "Smith", firstname = "John", income = 1100 };
income.Add(fi);
fi = new FamilyIncome { familyId = -100, lastname = "Smith", firstname = "Cole", income = 840 };
income.Add(fi);
fi = new FamilyIncome { familyId = -110, lastname = "Jones", firstname = "Harry", income = 1270 };
income.Add(fi);
fi = new FamilyIncome { familyId = -110, lastname = "Jones", firstname = "Diane", income = 970 };
income.Add(fi);
fi = new FamilyIncome { familyId = -111, lastname = "Jones", firstname = "Richard", income = 1600 };
income.Add(fi);
return income;
}
Let's assume the class representing your data item looks like this:
class DataItem
{
public int FamilyId { get; set; }
public string FamilyName { get; set; }
public string FirstName { get; set; }
public decimal Salary { get; set; }
}
Then your data should be presented as
private static DataItem[] items = new[]
{
new DataItem { FamilyId = -100, FamilyName = "Smith", FirstName = "Jane", Salary = 1000},
new DataItem { FamilyId = -100, FamilyName = "Smith", FirstName = "John", Salary = 1100},
new DataItem { FamilyId = -100, FamilyName = "Smith", FirstName = "Cole", Salary = 840},
new DataItem { FamilyId = -110, FamilyName = "Jones", FirstName = "Harry", Salary = 1270},
new DataItem { FamilyId = -110, FamilyName = "Jones", FirstName = "Diane", Salary = 870},
new DataItem {FamilyId = -111, FamilyName = "Jones", FirstName = "Richard", Salary = 1560},
};
The query producing the desired output will be the following:
var groupedItems =
from item in items
group item by new {item.FamilyId, item.FamilyName}
into family
select new {family.Key.FamilyId, family.Key.FamilyName, Sum = family.Sum(item => item.Salary)};
And to output these grouped items you can use something like
foreach (var groupedItem in groupedItems)
{
Console.WriteLine(
"{0}\t{1}\t{2}",
groupedItem.FamilyId,
groupedItem.FamilyName,
groupedItem.Sum);
}
Hope this helps
Lets assume I have a list of Persons, in the List I have the following objects:
Person = { ID= 1, State="CA"}
Person = { ID= 2, State="PA"}
Person = { ID= 1, State="NY"}
Person = { ID= 1, State="OH"}
Person = { ID= 3, State="FL"}
Person = { ID= 2, State="KC"}
How do I get a new List Where I can have new Persons by ID only once and if repeated get the State value and put it in the new Person object separated by comma. For example the new List will be
Person = { ID= 1, State="CA,NY,OH"}
Person = { ID= 2, State="PA,KC"}
Person = { ID= 3, State="FL"}
Is there a way to achieve this?
Use Enumerable.GroupBy and String.Join:
var result = persons.GroupBy(p => p.ID)
.Select(g => new Person{
ID = g.Key,
State = string.Join(",", g.Select(p => p.State))
}).ToList();
here is the extension method version
var persons = Person.GroupBy(p => p.ID).Select(p => new Person() { ID = p.Key, State = String.Join(",", p.Select(p2 => p2.State).ToArray()) }).ToList();
I have an SQL code like;
Select GroupName, sum(LineAmount) as Total, WeekNumber,
ROW_NUMBER() over (partition by WeekNumber order by sum(LineAmount) desc) as RowNum
from
Invoices
where
month(InvoiceDate)=month(getdate())
group by
GroupName,WeekNumber
I would like to convert this to LINQ, but no luck. I am using LINQ to Object. Any help would be appreciated.
TIA
EDIT : Here is some sample data, and the expected result.
public class Invoice
{
public string GroupName { get; set; }
public int LineAmount { get; set; }
public int WeekNum { get; set; }
}
List<Invoice> theData = new List<Invoice>();
theData.Add(new Invoice { GroupName = "A", LineAmount = 1, WeekNum = 1});
theData.Add(new Invoice { GroupName = "A", LineAmount = 2, WeekNum = 1 });
theData.Add(new Invoice { GroupName = "A", LineAmount = 3, WeekNum = 1 });
theData.Add(new Invoice { GroupName = "A", LineAmount = 2, WeekNum = 2 });
theData.Add(new Invoice { GroupName = "A", LineAmount = 3, WeekNum = 2 });
theData.Add(new Invoice { GroupName = "A", LineAmount = 4, WeekNum = 2 });
theData.Add(new Invoice { GroupName = "B", LineAmount = 4, WeekNum = 1 });
theData.Add(new Invoice { GroupName = "B", LineAmount = 3, WeekNum = 1 });
theData.Add(new Invoice { GroupName = "B", LineAmount = 7, WeekNum = 2 });
theData.Add(new Invoice { GroupName = "B", LineAmount = 6, WeekNum = 2 });
theData.Add(new Invoice { GroupName = "B", LineAmount = 5, WeekNum = 2 });
I have removed "where" from my first query as its not a problem at the moment.
theData
.GroupBy(g => new {g.GroupName, g.WeekNum}, (key, gg) => new {key.GroupName, key.WeekNum, Total = gg.Sum(g => g.LineAmount)})
.GroupBy(g => g.WeekNum, (weekNum, gg) => gg.OrderByDescending(g => g.Total).Select((g,i) => new {g.GroupName, g.Total, g.WeekNum, RowNum = i}))
.SelectMany(g => g)
You have not specified the language you need it in. Here is the code in C#
int index = 0;
var filteredInvoices = (from i in invoices
where i.InvoiceDate.Month == DateTime.Now().Month
group i by new { i.GroupName, i.WeekNumber }
into ig
select new {i.GroupName, Total = ig.Sum(i => i.LineAmount), i.WeekNumber, RowNum = ++index}).OrderByDescending(n => n.Total);
filteredInvoices should have the result that you want. Also I am assuming that the i.InvoiceDate is of type DateTime.
Serg Rogovtsev answer gives me expected result. And the below code is what I have done. Don't know which performs better, but results are same.
(theData.GroupBy(f => new { f.GroupName, f.WeekNum})
.Select(r => new {r.Key.WeekNum, r.Key.GroupName, Total = r.Sum(f => f.LineAmount)}))
.GroupBy(r => new {r.WeekNum}).SelectMany(
g =>
g.OrderByDescending(f => f.Total).Select(
(f, index) => new { f.GroupName, f.Total, f.WeekNum, Ix = index + 1 }))
I have an array of Person pocos, populated below. I'm trying display them alphabetically by Province, then by LastName within the Province. I'm using grouping and I can get the Provinces sorted fine, just not sure how to order the people within the province group.
This code:
Person[] people = new Person[]
{
new Person() { FirstName = "Tony", LastName = "Montana", Age = 39, HomeProvince = "Ontario" },
new Person() { FirstName = "Bill", LastName = "Smith", Age = 23, HomeProvince = "Ontario" },
new Person() { FirstName = "Jane", LastName = "Doe", Age = 23, HomeProvince = "Alberta" },
new Person() { FirstName = "John", LastName = "Doe", Age = 23, HomeProvince = "Alberta" },
new Person() { FirstName = "Alex", LastName = "DeLarge", Age = 19, HomeProvince = "British Columbia" },
new Person() { FirstName = "Travis", LastName = "Bickle", Age = 42, HomeProvince = "Quebec" },
new Person() { FirstName = "Ferris", LastName = "Beuller", Age = 17, HomeProvince = "Manitoba" },
new Person() { FirstName = "Maggie", LastName = "May", Age = 23, HomeProvince = "Ontario" },
new Person() { FirstName = "Mickey", LastName = "Mouse", Age = 93, HomeProvince = "Alberta" },
new Person() { FirstName = "Frank", LastName = "Darabont", Age = 49, HomeProvince = "Ontario" }
};
var query =
from person in people
group person by person.HomeProvince into g
orderby g.Key
select new { Province = g.Key, People = g };
foreach (var prov in query)
{
Console.WriteLine("{0}: ", prov.Province);
foreach (var person in prov.People)
{
Console.WriteLine(" {0} {1}, {2}", person.FirstName, person.LastName, person.Age);
}
}
Gives me this output:
Alberta:
Jane Doe, 23
John Doe, 23
Mickey Mouse, 93
British Columbia:
Alex DeLarge, 19
Manitoba:
Ferris Beuller, 17
Ontario:
Tony Montana, 39
Bill Smith, 23
Maggie May, 23
Frank Darabont, 49
Quebec:
Travis Bickle, 42
As you can see, the Provinces are listed alphabetically but how do I list the people within the province (i.e for Ontario I want this order: Darabont, Montana, May, Smith).
Assuming that you want alphabetical order by LastName then change this:
select new { Province = g.Key, People = g };
to:
select new { Province = g.Key, People = g.OrderBy(p => p.LastName) };
But note that your example "Darabont, Montana, May, Smith" is not quite in alphabetical order. I assume that this was just a mistake on your part, but if this is actually the order you want, please explain the rule you are using to generate this ordering.
should be able to, after the select statement, to orderby(person => person.LastName);
I have a Batch with BatchItems entered by multiple users. I'm trying to not only get the subtotal per user for a single batch, but also grand total for that same batch regardless of the user grouping. Its this last part that I can't figure out. How might I get that total in order to return it as a list?
from b in context.BatchItem
where b.BatchId == batchId
group b by b.CreatedByUser into g
select new
{
BatchName = g.FirstOrDefault<BatchItem>().Batch.Name,
User = g.Key,
UserBatchCount = g.Count<BatchItem>(),
// something like this is what I can't figure out
TotalBatchCount = b.Count<BatchItem>()
}
Not sure, but try this:
from b in context.BatchItem
let cnt = context.BatchItem.Count()
b.BatchId == batchId
group b by b.CreatedByUser into g
select new
{
BatchName = g.FirstOrDefault<BatchItem>().Batch.Name,
User = g.Key,
UserBatchCount = g.Count<BatchItem>(),
// something like this is what I can't figure out
TotalBatchCount = cnt
}
var batch1 = new { Name = "Batch A", BatchId = 1, CreatedByUser = "David" };
var batch2 = new { Name = "Batch A", BatchId = 1, CreatedByUser = "Mike" };
var batch3 = new { Name = "Batch B", BatchId = 2, CreatedByUser = "Cathy" };
var batch4 = new { Name = "Batch B", BatchId = 2, CreatedByUser = "Cathy" };
var batch5 = new { Name = "Batch B", BatchId = 2, CreatedByUser = "David" };
var batch6 = new { Name = "Batch C", BatchId = 3, CreatedByUser = "Henry" };
var batchItem = new[] { batch1, batch2, batch3, batch4, batch5, batch6 }.ToList();
var result =
batchItem.Where(b => b.BatchId == batchId)
.GroupBy(b => b.BatchId, b => b)
.SelectMany(g =>
g.GroupBy(c => c.CreatedByUser, c => c)
.SelectMany(sg =>
sg.Select(c => new
{
BatchName = g.First().Name,
UserName = c.CreatedByUser,
UserBatchCount = sg.Count(),
TotalBatchCount = g.Count()
})
)
);
Audit Log: Removed previous two code blocks.