Optimal LinqToSql GroupBy query, in 1:m relationship [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have two database tables (connected with relation 1:m):
Location (locId, locName)
1, USA
2, Germany
3, Spain
Sublocations (subLocId, subLocName, locId)
1, Denver, 1
2, Detroit, 1
3, New York, 1
4, Hamburg, 2
5, Berlin, 2
6, Munich, 2
7, Madrid, 3
8, Barcelona, 3
9, Valencia, 3
With using Linq to Sql, I need to fill the LocationDto, like this:
LocationDto (locId, subLocId, name)
1, null, USA
1, 1, Denver
1, 2, Detroit
1, 3, New York
2,null, Germany
2, 4, Hamburg
2, 5, Berlin
2, 6, Munich
3,null, Spain
3, 7, Madrid
3, 8, Barcelona
3, 9, Valencia

Create a new class to hold the joined objects:
public class JoinedLocations
{
public int locId{get;set;}
public int? subLocId{get;set;}
public string Description{get;set;}
}
and then run this query
var query =
Location
.GroupJoin
(
Sublocations.DefaultIfEmpty(),
l=>l.locId,
s=>s.locId,
(l,s)=>new {l,s}
)
.SelectMany
(
x=>
x.s.DefaultIfEmpty
(
new Sublocations
{
subLocId=-1,
subLocName="",
locId=-1
}
),
(l,s)=>
new JoinedLocations
{
locId=l.l.locId,
subLocId=s.subLocId,
Description = (s.subLocId==-1?l.l.locName:s.subLocName)
}
)
.Union
(
loc
.Select
(
x=>
new JoinedLocations
{
locId=x.locId,
subLocId=null,
Description = x.locName
}
)
)
.OrderBy(x=>x.locId)
.ThenBy (x => x.subLocId)
This will give you the results you want.

Related

Filling a Two-Dimensional Array with 2 values

First. I'm sorry if the question the question is badly formulated because I don't really understand the question myself.
Hello,
I'm currently helping a friend with his practice tasks about 2-Dimensional Arrays.
The following task is: Expand the array with the missing columns. Fill the column with two values each.
Now my question is how? Is it even possible to put 2 values in one?
For a better understanding, see this code:
static int[][] BSP = {
new int[] { 1, 2, 3, 4 },
new int[] { 1, 2, 3 } ,
new int[] { 1, 2, 3, 4, 5, 6 }
};
Now we should expand the array to the task I mentioned above. I understand the Task like this:
Instead of one value there should be 2.
Can you help me or did I misunderstood the question.
When you are going to expand (or shrink) try to use list List<T> instead of array T[]. We want to extend lines while keeping columns intact, so we can use List<T[]> - list of arrays:
static List<int[]> BSP = new List<int[]>() {
new int[] { 1, 2, 3, 4 },
new int[] { 1, 2, 3 },
new int[] { 1, 2, 3, 4, 5, 6 },
};
then you can just Add to extend (and RemoveAt to shrink):
// 4th row with 2 values: 12 and 21
BSP.Add(new int[] { 12, 21 });

Remove elements from List A that are in List B while keeping any duplicates in List A [duplicate]

This question already has answers here:
Removing a list of objects from another list
(5 answers)
Closed 1 year ago.
I have a List A of strings that I want to trim of all elements that also appear in List B, while keeping the duplicate values in List A.
Such that with an input like:
List A: [1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7]
List B: [2, 6, 8, 9, 10]
I am hoping to get an output like:
List C: [1, 3, 3, 4, 5, 7, 7, 7]
I originally thought this could be accomplished using ListA.Except(ListB), but that function leaves only one element of a duplicate value.
In the program, List B is much bigger than the example given and there are multiple instances of List A to go through, so I'd like to avoid nested for loops. I don't necessarily care about keeping the original order of List A either, since the output of this will be the input of a frequency dictionary.
Am I overlooking something? Is there a faster option than using nested for loops?
You can use List<T>.RemoveAll()
var a = new[] { 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7 }.ToList();
var b = new[] { 2, 6, 8, 9, 10 }.ToList();
var c = a.Select(i => i).ToList(); //make a copy of 'a'
c.RemoveAll(i => b.Contains(i));
You can just use a Where() clause with a Contains() in it. To avoid O(n²) complexity (which is really what you're trying to avoid when you say "nested for loops," you can create a HashSet out of List B.
var setB = listB.ToHashSet();
var aMinusB = listA.Where(item => !setB.Contains(item)).ToList();
You can use LINQ for this using any:
var result = listA.Where(el1 => !listB.Any(el2 => el2 == el1)).ToList();

C# Console Application, how to make all results equals totalResult? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
How do I make the last result equal the first, second, third, and fourth result combined?
If all results are 10 points except the last one, then the last one should be 40 points. The last result is the total result.
int[] result = new int[5] { 0, 0, 0, 0, 0 };
Here you go
int[] result = { 1, 2, 3, 4, 0 };
result[result.Length - 1] = result.Take(result.Length - 1).Sum(); // 1 + 2 + 3 + 4 = 10
//result = { 1, 2, 3, 4, 10 };

Generate sequences number with repetition [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following code:
var result = AllSequences(1, 10, 3);
public static IEnumerable<List<int>> AllSequences(int start, int end, int size)
{
if (size == 0)
return Enumerable.Repeat<List<int>>(new List<int>(), 1);
return from i in Enumerable.Range(start, end - size - start + 2)
from seq in AllSequences(i, end, size - 1)
select new List<int> { i }.Concat(seq).ToList();
}
Result:
1,1,1
1,1,2
1,1,3
1,1,4
....
2,2,2
2,2,3
2,2,4
But before coming to this sequence, wish you were like this:
2,1,1
2,1,2
2,1,3
2,1,4
.....
I'm having trouble generating sequence is, I'm using LINQ to gain performance in this loop
I'm a bit confused by your question but if you want the sequence to run through each digit from 1 to 10, for all permutations try something like this.
I'm not advocating the use of LINQ here, just trying to make as few changes to your code as possible.
public static IEnumerable<List<int>> AllSequences(int start, int end, int size)
{
if (size == 0)
return Enumerable.Repeat<List<int>>(new List<int>(), 1);
return from i in Enumerable.Range(start, end)
from seq in AllSequences(start, end, size - 1)
select new List<int> { i }.Concat(seq).ToList();
}
Results will be
1, 1, 1
1, 1, 2
... etc
1, 1, 10
1, 2, 1
1, 2, 2
... etc
1, 10, 8
1, 10, 9
1, 10, 10
2, 1, 1
2, 1, 2
.... etc
10, 10, 10

Is there a way to organise an IEnumerable into batches in column-major format using Linq?

In several of my most recent projects, I've found the need to divide a single collection up into m batches of n elements.
There is an answer to this question that suggests using morelinq's Batch method. That is my preferred solution (no need to re-invent the wheel and all that).
While the Batch method divides the input up in row-major format, would it also be possible to write a similar extension that divides the input up in column-major format? That is, given the input
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
you would call ColumnBatch(4), generating an output of
{
{ 1, 4, 7, 10 },
{ 2, 5, 8, 11 },
{ 3, 6, 9, 12 }
}
Does morelinq already offer something like this?
UPDATE: I'm going to change the convention slightly. Instead of using an input of 4, I'll change it to 3 (the number of batches rather than the batch size).
The final extension method will have the signature
public static IEnumerable<IEnumerable<T>> ToColumns<T>(this IEnumerable<T> source, int numberOfColumns)
which should be clear to whoever is implementing the method, and does not require multiple enumerations.
int[] arr = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
int i=0;
var result = arr.GroupBy(x => i++ % 3).Select(g => g.ToList()).ToList();

Categories

Resources