linq query to list that adds position of result - linq

I have the linq query that produces the result below:
var result = from x in model.SITEs
where x.SiteId == homeSite
select new { x.SiteId,
x.SiteAlloc1,
x.SiteAlloc2,
x.SiteAlloc3,
x.SiteAlloc4 });
SiteId SiteAlloc1 SiteAlloc2 SiteAlloc3 SiteAlloc4
======================================================
1 5 3 2 4
But what I need is something more like this, where the Rank is the position of the SiteId in the result.
SiteId Rank
==================
1 1
2 4
3 3
4 5
5 2

var result = from x in model.SITEs
where x.SiteId == homeSite
select new { x.SiteId,
x.SiteAlloc1,
x.SiteAlloc2,
x.SiteAlloc3,
x.SiteAlloc4 }).
Select((t,u) => new {
SiteId = t.SiteId,
SiteAlloc1 = t.SiteAlloc1,
SiteAlloc2 = t.SiteAlloc2,
SiteAlloc3 = t.SiteAlloc3,
SiteAlloc4 = t.SiteAlloc4,
Rank = u + 1));
Where u is the index (0 based, that's why I added 1), or in your case the rank and t is the selected object

Related

SpriteKit for loop

Hi I'm trying to follow a tutorial on Ray Wenderlich site
[http://www.raywenderlich.com/76740/make-game-like-space-invaders-sprite-kit-and-swift-tutorial-part-1][1]
so I'm going thru the functions breaking it down so i can get an understanding of how it works I've commented out stuff which i think i understand but this bit has me stumped
thanks for looking
the for loop whats the var row = 1 at the beginning doing ?
I've only ever done for lops like
for Position in 0...9
{
// do something with Position ten times
}
then whats the % in if row %3 mean?
for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1
hers the rest of the code
func makeInvaderOfType(invaderType: InvaderType) -> (SKNode) // function passes in a enum of atype,btype,ctype and returns sknode
{
var invaderColor: SKColor// variable for the colour
switch(invaderType)// switch statment if we pass in atype we will get red
{
case .AType:
invaderColor = SKColor.redColor()
case .BType:
invaderColor = SKColor.greenColor()
case .CType:
invaderColor = SKColor.blueColor()
default:
invaderColor = SKColor.blueColor()
}
let invader = SKSpriteNode(color: invaderColor, size: kInvaderSize)//variable of a skspritenode with color from switch statement size from vairiabe kinvadersize
invader.name = kInvaderName // name is invader fron let kinvadername
return invader //return the spritenode with color size name
}
func setupInvaders()
{
let baseOrigin = CGPoint(x:size.width/3, y:180) // vairible to hold cgpoint screen size /3 width 180 height
for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1
{
invaderType = .BType
} else
{
invaderType = .CType
}
let invaderPositionY = CGFloat(row) * (kInvaderSize.height * 2) + baseOrigin.y// varible to hold cgfloat row ? think its the incriment of the for loop times 16 times 2 = 32 plus 180 first time is 212 then 244
/* so if ive got his rightthe sum goes row = 1 kinvadersize.hieght *2 = 32 + baseoringin.y = 180
1 * 32 +180 = 212
2 * 32 + 180 = 392 but its 244
*/
println(row)
var invaderPosition = CGPoint(x:baseOrigin.x, y:invaderPositionY) // varible to hold cgpoint
println(invaderPosition.y)
for var col = 1; col <= kInvaderColCount; col++
{
var invader = makeInvaderOfType(invaderType)// varible that runs function and return the spritenode with color size name????
invader.position = invaderPosition
addChild(invader)
invaderPosition = CGPoint(x: invaderPosition.x + kInvaderSize.width + kInvaderGridSpacing.width, y: invaderPositionY)
}
}
}
If I understand your question correctly, here's the answer. Based on this code:
for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1
The first line means:
var row = 1: given a new variable, row, with a value of 1
row <= kInvaderRowCount: as long as the variable row is less than or equal to kInvaderRowCount, keep running the for loop
row++: after each time the loop is run, increment (increase) the value of row by 1
As for the "%", that is the modulo operator. It returns the remainder after a division operation on integer values. So if 7 divided by 3 = 2, with a remainder of 1, then
7 / 3 = 2
7 % 3 = 1
The modulus operator results in an integer. While 1 / 3 = 0.33..., 1 % 3 = 1. Because the remainder of 1 divided by 3 is 1.
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
see also: How Does Modulus Divison Work.

LINQ filtering on a Dictionary<string, IList<string>>

I have code similar to this:
var dict = new Dictionary<string, IList<string>>();
dict.Add("A", new List<string>{"1","2","3"});
dict.Add("B", new List<string>{"2","4"});
dict.Add("C", new List<string>{"3","5","7"});
dict.Add("D", new List<string>{"8","5","7", "2"});
var categories = new List<string>{"A", "B"};
//This gives me categories and their items matching the category list
var result = dict.Where(x => categories.Contains(x.Key));
Key Value
A 1, 2, 3
B 2, 4
What I would like to get is this:
A 2
B 2
So the keys and just the values that are in both lists. Is there a way to do this in LINQ?
Thanks.
Easy peasy:
string key1 = "A";
string key2 = "B";
var intersection = dict[key1].Intersect(dict[key2]);
In general:
var intersection =
categories.Select(c => dict[c])
.Aggregate((s1, s2) => s1.Intersect(s2));
Here, I'm utilizing Enumerable.Intersect.
A somewhat dirty way of doing it...
var results = from c in categories
join d in dict on c equals d.Key
select d.Value;
//Get the limited intersections
IEnumerable<string> intersections = results.First();
foreach(var valueSet in results)
{
intersections = intersections.Intersect(valueSet);
}
var final = from c in categories
join i in intersections on 1 equals 1
select new {Category = c, Intersections = i};
Assuming we have 2 and 3 common to both lists, this will do the following:
A 2
A 3
B 2
B 3

get the sum of the maxs group by

I have this table
EquipmentId Value Date
1 2 11/04/2013
1 1 11/04/2013
2 3 11/04/2013
2 2 10/04/2013
2 5 10/04/2013
3 1 10/04/2013
3 3 11/04/2013
I want to group these items by date, and have a dictionary with the date as a key and the sum of the maxs of the all equipments values in that day
the result would be like this
[10/04/2013: 6] // 6 = 5 (as the max of values of the the equipmetId 2) + 1 (as the max of values of the the equipmetId 3)
[11/04/2013: 5] // 5 = 2(as the max of values of the the equipmetId 1) + 3(as the max of values of the the equipmetId 3)
I managed to make the query to get this without the sum, meaning for only one equipment.
var consumptionValues = (from c in context.ConsumptionSet
join pi in context.PropertiesInstanceSet on c.PropertiesInstanceID equals pi.PropertiesInstanceID
join ep in context.EquipmentPropertiesSet on pi.EquipmentPropertiesID equals ep.EquipmentPropertiesID
join e in context.EquipmentSet on ep.EquipmentID equals e.EquipmentID
where (e.EquipmentID == equipmentId && pi.ProprietesName == ProprietesName.Energy && c.Date <= DateTime.Now && c.Date >= firstDayDate)
group c by SqlFunctions.DatePart("weekday", c.Date) into grp
select new
{
dayOfWeek = (DayOfWeek)grp.Key.Value - 1,
value = grp.Max(c => c.Value),
}).ToDictionary(c => c.dayOfWeek.ToString(), c => c.value);
It's the complete query with all the joins, in the example I just gave a simplified example.
Is it possible to do this in one single query ?
I have to say I'm not sure it will work, but you should give it a shot:
var consumptionValues = (from c in context.ConsumptionSet
join pi in context.PropertiesInstanceSet on c.PropertiesInstanceID equals pi.PropertiesInstanceID
join ep in context.EquipmentPropertiesSet on pi.EquipmentPropertiesID equals ep.EquipmentPropertiesID
join e in context.EquipmentSet on ep.EquipmentID equals e.EquipmentID
where (e.EquipmentID == equipmentId && pi.ProprietesName == ProprietesName.Energy && c.Date <= DateTime.Now && c.Date >= firstDayDate)
group new { c, e } by SqlFunctions.DatePart("weekday", c.Date) into grp
select new
{
dayOfWeek = (DayOfWeek)grp.Key.Value - 1,
value = grp.GroupBy(i => i.e.EquipmentID).Sum(g => g.Max(i => i.c.Value)),
}).ToDictionary(c => c.dayOfWeek.ToString(), c => c.value);

Linq query with datatable [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have this datatable result in c#
Date Employee Job1 Job2 Job3
1/1/2012 a 1 1 1
1/1/2012 b 2 2 2
1/1/2012 c 2 1 4
1/1/2012 d 4 2 1
1/2/2012 a 3 2 5
1/2/2012 b 2 2 2
1/2/2012 c 3 3 3
1/2/2012 d 1 1 1
1/3/2012 a 5 5 5
1/3/2012 b 2 2 6
1/3/2012 c 1 1 1
1/3/2012 d 2 3 4
2/1/2012 a 2 2 2
2/1/2012 b 5 5 2
2/1/2012 c 2 2 2
2/2/2012 a 3 3 3
2/2/2012 b 2 3 3
3/1/2012 a 4 4 2
Now I want a result like this:
Job1:
Employee January February March
A 9 5 4
B 6 7
C 6 2
D 7
Please, can anybody suggest me how to do this with "Linq" in c#?
This might work (or give you at least an idea):
var monthEmpGroups = tblEmpJobs.AsEnumerable()
.Select(r => new
{
Row = r,
Employee = r.Field<String>("Employee"),
Year = r.Field<DateTime>("Date").Year,
Month = r.Field<DateTime>("Date").Month
})
.GroupBy(x => x.Employee);
DataTable tblMonthResultJob1 = new DataTable();
tblMonthResultJob1.Columns.Add("Employee", typeof(string));
var dtf = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat;
foreach (var empGroup in monthEmpGroups)
{
string employee = empGroup.Key;
var newRow = tblMonthResultJob1.Rows.Add();
newRow["Employee"] = employee;
var empMonthGroup = empGroup.GroupBy(mg => new { mg.Year, mg.Month });
foreach (var empYearMonthGroup in empMonthGroup)
{
int year = empYearMonthGroup.Key.Year;
int month = empYearMonthGroup.Key.Month;
string colName = string.Format("{0} {1}", dtf.GetMonthName(month), year);
if (!tblMonthResultJob1.Columns.Contains(colName))
tblMonthResultJob1.Columns.Add(colName, typeof(int));
int empJob1Count = empYearMonthGroup.Sum(x => x.Row.Field<int>("Job1"));
newRow[colName] = empJob1Count;
}
}
// do the same for the other job types
Update If you need to add a "total-row" at the "end" as commented:
DataRow totalRow = tblMonthResultJob1.Rows.Add();
totalRow["Employee"] = "ALL";
var monthGroups = tblEmpJobs.AsEnumerable()
.Select(r => new {
Row = r,
Year = r.Field<DateTime>("Date").Year,
Month = r.Field<DateTime>("Date").Month
})
.GroupBy(x => new { x.Year, x.Month });
foreach (var monthGroup in monthGroups)
{
int yearAll = monthGroup.Key.Year;
int monthAll = monthGroup.Key.Month;
string colName = string.Format("{0} {1}", dtf.GetMonthName(monthAll), yearAll);
if (!tblMonthResultJob1.Columns.Contains(colName))
tblMonthResultJob1.Columns.Add(colName, typeof(int));
int allJob1Count = monthGroup.Sum(x => x.Row.Field<int>("Job1"));
totalRow[colName] = allJob1Count;
}
Update2
I am getting error system.dbnull on this line int
empJob1Count = empYearMonthGroup.Sum(x => x.Row.Field<int>("Job1"));
I think there
are some null values and it is not able to cast null values while
doing sum. Please help, how should i resolve this
You can use this code to default an int? to zero:
var empYearMonthCount = empYearMonthGroup.Sum(x =>
{
int? job1 = x.Row.Field<int?>("Job1");
int value = 0;
if(job1.HasValue) value = job1.Value;
return value;
});

Linq select subgroup

I have the following in my db table:
- MailingId | GroupName | ServiceId
- 1 | group1 | 3
- 2 | group1 | 5
- 3 | group1 | 8
- 4 | group2 | null
- 5 | group3 | null
...
In my view i have 2 groups of checkboxes:
1) (services) with id's 3,5,8 (serviceId).
2) and a list of checkboxes for mailing groups (group1, group2, group3)
I need to select the following using LINQ:
Select rows that I have selected in ServiceId checkbox list PLUS any other. For example if I check off ServiceId's (3 and 5) and group "Group3" then my output would be rows MailingId: 1, 3 and 5. HOWEVER, if I select ANY service from (first group of checkboxes) AND DO NOT select "Group1" from mailing group checkboxes then rows with Group1 SHOULD NOT be in the output.
I'm using EF4. Please help.
Thanks
The 2 arrays would be the selections that are posted from your view
int[] selectedservices = {3,5};
string[] selectedgroups = {"group3"};
using (Model model = new Model())
{
bool b = selectedservices.Contains(1);
var mailinglists = from m in model.MalingSet
where selectedgroups.Contains(m.GroupName)
&& ((m.ServiceId.HasValue && selectedservices.Contains(m.ServiceId.Value)) || m.ServiceId.HasValue == false)
select m.MailingId;
}
Try something like this.
var mailingGroup =
from m in Mailings
where m.ServiceId != null // or whatever other condition
group m by m.GroupName into g
select new
{
groupName = g.Key,
mailings = g
};
It's a Where clause no?
var a = new {m = 1, g = "group1", sid = 3};
var b = new {m = 2, g = "group1", sid = 5};
var c = new {m = 3, g = "group1", sid = 8};
var d = new {m = 4, g = "group2", sid = 0};
var e = new {m = 5, g = "group3", sid = 0};
var l = new List<dynamic>{a,b,c,d,e};
l.Where(it => ( new ArrayList{3, 5}).Contains(it.sid)
|| (new ArrayList{1, 5}).Contains(it.m)).Dump();
http://www.linqpad.net/

Resources