For y.Value as Excelwert I get null.
My code:
Dictionary<String, List<Excelwert>> kernListe = myList.Where(x => x.Key.Equals(nameDerList))
.ToDictionary(x => x.Key, y => { return new List<Excelwert>(){ y.Value as Excelwert}; });
myList is Dictionary<string,object>.
This is how the Valuelooks like in my watch.
What shall I change ?
Related
I have a scenario where in case there is a specific boolean value satisfied (office_debit_total line) I can get amount directly from a column otherwise I need to calculate it by grouping some specific values, here's the code:
var result = products.Select(p => new ResponseDto()
{
customer_id = p.CustomerId,
office_debit_date = p.OfficeDebitDate.Value.ToString(),
office_debit_id = p.OfficeDebitId.ToString(),
office_debit_total = p.OfficeEnum == SomeEnum.ValueType ? p.OfficeAmount.ToString() : totalAmounts[p.OfficeDebitId].ToString(),
payment_method = p.PaymentMethod.Value.ToString(),
}).ToList();
As it's possible to be seen office_debit_total is calculated depending on enum value, and here's dictionary that I'm using to get grouped data:
Dictionary<string, decimal> totalAmounts = products
.Where(p => p.ProductType == ProductType.ValueType)
.GroupBy(p => new { p.OfficeDebitId, p.OfficeDebitDate, p.PaymentMethod })
.ToDictionary(x => x.Key.OfficeDebitId, x => x.Sum(p => p.Amount));
But I have receiving following error message:
An item with the same key has already been added.
I've tried writing .ToLookup instead of .ToDictionary but that didn't helped me..
Thanks guys
Cheers
If your dictionary has only OfficeDebitId as key then you need to group by only by it:
var totalAmounts = products
.Where(p => p.ProductType == ProductType.ValueType)
.GroupBy(p => p.OfficeDebitId)
.ToDictionary(x => x.Key, x => x.Sum(p => p.Amount));
or use full anonymous object as key:
var totalAmounts = products
.Where(p => p.ProductType == ProductType.ValueType)
.GroupBy(p => new { p.OfficeDebitId, p.OfficeDebitDate, p.PaymentMethod })
.ToDictionary(x => x.Key, x => x.Sum(p => p.Amount));
Or with value tuple as key:
var totalAmounts = products
.Where(p => p.ProductType == ProductType.ValueType)
.GroupBy(p => (p.OfficeDebitId, p.OfficeDebitDate, p.PaymentMethod))
.ToDictionary(x => x.Key, x => x.Sum(p => p.Amount));
Why not this:
Dictionary<string, decimal> totalAmounts = products
.Where(p => p.ProductType == ProductType.ValueType)
.GroupBy(p => p.OfficeDebitId)
.ToDictionary(x => x.Key, x => x.Sum(p => p.Amount));
You might need it in this way (You can use value tuple):
Dictionary<(string OfficeDebitId, System.DateTime? OfficeDebitDate, Enumerations.PaymentMethod? PaymentMethod), decimal> totalAmounts = products
.Where(p => p.ProductType == ProductType.ValueType)
.GroupBy(p => new { p.OfficeDebitId, p.OfficeDebitDate, p.PaymentMethod })
.ToDictionary(x => (x.Key.OfficeDebitId, x.Key.OfficeDebitDate, x.Key.PaymentMethod ), x => x.Sum(p => p.Amount));
I have this LINQ which does the job I want
var query = context.MasterTemplateOfficeTag
.Join(context.Tag, x => x.TagId, y => y.Id, (x, y) => new { y.Name })
.ToList();
Though my question is I would like the LINQ to return a list<String> as the Select syntax => new { y.Name }) is of type string. Therefore if the compiler knows the return type, why I can't use list<String>?
I would want something like this
List<String> name = context.MasterTemplateOfficeTag
.Join(context.Tag, x => x.TagId, y => y.Id, (x, y) => new { y.Name })
.ToList();
Is this possible to do?
Thanks
Well
new { y.Name }
is an anonymous object with a single string field (Name). Drop new {...} wrapping and return string:
List<String> name = context
.MasterTemplateOfficeTag
.Join(
context.Tag,
x => x.TagId,
y => y.Id,
(x, y) => y.Name ) // <- Now we return string: y.Name
.ToList();
new { y.Name }) creates an anonymous object with a Name property.
You need to just return y.Name to be able to use List<string>
Instead of returning an anonymous object, just return the string
List<String> name = context.MasterTemplateOfficeTag
.Join(context.Tag, x => x.TagId, y => y.Id, (x, y) => y.Name)
.ToList();
I am trying to converting a Tuple<List<Guid>, string> to Dictionary<Guid, List<string>>. This is what I have so far:
var listOfTuples = GetListOfTuples(); // returns type List<Tuple<List<Guid>, string>>
var transformedDictionary = new Dictionary<Guid, List<string>>();
foreach (var listOfTuple in listOfTuples)
{
foreach (var key in listOfTuple.Item1)
{
if (!transformedDictionary.ContainsKey(key))
transformedDictionary[key] = new List<string> { listOfTuple.Item2 };
else transformedDictionary[key].Add(listOfTuple.Item2);
}
}
Is there a better way of doing this, perhaps using LINQ; SelectMany, Grouping, or toDictionary?
Update: I have tried this, but clearly not working:
listOfTuples.ToList()
.SelectMany(x => x.Item1,(y, z) => new { key = y.Item2, value = z })
.GroupBy(p => p.key)
.ToDictionary(x => x.Key, x => x.Select(m => m.key));
You are close. The problem is with selecting the right key and value
var result = listOfTuples.SelectMany(t => t.Item1.Select(g => (g, str: t.Item2)))
.GroupBy(item => item.g, item => item.str)
.ToDictionary(g => g.Key, g => g.ToList());
The mistake is here (y, z) => new { key = y.Item2, value = z } - you want the key to be the Guid and therefore instead of it being Item2 it should be z which is the Guid. So you can go with the way I wrote it or just
(y, z) => new { key = z, value = y.Item2 }
Also the .ToList() at the beginning is not needed. You say that listOfTuples already returns a list
I have a list of strings which contain X in them. I want to select list(s) with the minimum count of X in them. For example:
CountMin("AXBXX", "AAX") will return AAX.
How can I write this qith LINQ in a concise way ?
public static string CountMin(IList<string> inputList)
{
if (inputList == null || !inputList.Any()) return null;
var result = inputList.Select(s => new
{
Item = s,
Count => s.Count(ch => ch == 'X')
})
.OrderBy(item => item.Count).First().Item;
}
Snippet assumes that all elements on list are different to null. If you need it, it could be easily improved.
You can also omit temporary class:
inputList.OrderBy(s => s.Count(c => c == 'X')).First();
string[] list = {"AXBXX", "AAX", "AXX"};
string result = (from word in list
select new { word, wordLen = (word.Length - (word.Replace("X", "")).Length) })
.OrderBy(x => x.wordLen).First().word;
MessageBox.Show(result);
Here's an answer that will get you all of the minimum X strings from the list.
var listOfStrings = new List<string>()
{
"AXB",
"ABXXC",
"ABX",
};
var minimumXs =
listOfStrings
.GroupBy(x => x.Count(y => y == 'X'))
.OrderBy(x => x.Key)
.Take(1)
.SelectMany(x => x);
That gives me:
AXB
ABX
I am trying to convert a DataTable of the form
Key Value
1 A
1 B
1 C
2 X
2 Y
To a Dictionary
1 [A,B,C]
2 [X,Y]
The lambda expression I am using is
GetTable("..sql..").AsEnumerable().
.Select(r => new {Key = r.Field<int>("Key"), Val = r.Field<string>("Value")})
.GroupBy(g => g.Key)
.ToDictionary(a => a.Key, a => String.Join(",", a.Value))
But it fails with "Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer' because it is not a delegate type"
How can I accomplish this?
This does it:
GetTable("..sql..").AsEnumerable().
.Select(r => new {Key = r.Field<int>("Key"), Val = r.Field<string>("Value")})
.GroupBy(g => g.Key)
.ToDictionary(a => a.Key, a => String.Join(",", a.Select(x => x.Value).ToList()))
Here's another way you can do it...
GetTable("..sql..").AsEnumerable()
.GroupBy(x => x.Field<int>("Key"))
.ToDictionary(grp => grp.Key, x => x.Select(y => y.Field<string>("Value")).ToList());
var foo = GetTable("").AsEnumerable()
.ToLookup(x => x.Key, x => x.Value);
foreach(var x in foo)
{
foreach(var value in x)
{
Console.WriteLine(string.Format("{0} {1}", x.Key, value));
}
}