I have the following data in a table:
e.g. data
0, 'Ford'
1, 'Toyota, Toyota'
2, 'BMW'
3, 'Porsche, Porsche'
4, 'BMW'
I need to place this data in the following type List<Tuple<int, string>> carList so that the results within my list would appear as follows:
0, 'Ford'
1, 'Toyota'
2, 'BMW'
3, 'Porsche'
4, 'BMW'
using the following pseudo code:
while (SQLiteDataReader.Read())
{
carList.Add
(
new Tuple<int, string> (
SQLiteDataReader.GetInt32(0) ,
SQLiteDataReader.GetString(1).[Some extension method to produce unique items]
);
)
}
Note, when there are items with duplication (Toyota, Porsche) , the duplication will always be the same name. i.e you won't get something like 'Toyota, Ford'.
Is there some extension method that would remove the duplication part?
This should do the trick:
SQLiteDataReader.GetString(1).Split(',').First().Trim()
If you're looking to do the whole thing through a linq query, this should work.
If you're just looking to fix your pseudocode, then scottm's solution should work.
LinqDataContext db = new LinqDataContext();
List<Tuple<int, string>> results =
db.Cars.AsEnumerable()
.Select(c => Tuple.Create(c.id, c.Make.Split(',')[0].Trim()))
.ToList();
Related
Print top value and its duplicate values present in List
Suppose List is ordered list.
List<Tuple<int, string, string>> result = new List<Tuple<int, string, string>> {
{4, "am", "I am the One"}
{4, "am" , "I am human"}
{2, "one", "zero plus one is one"}
{1, "is", "this is list"}
};
Selected output should Top int value and its duplicate if present.
Top according to int values is : 4. Duplicates are 1st and 2nd entries of list.
Output:
4, am, I am the One
4, am , I am human
Can anyone code to get max value and its duplicate?
I think this will do it:
List<Tuple<int, string, string>> maxTuples =
result.Where(r => r.Item1 == (result.Max(m => m.Item1))).ToList();
You are getting the maximum value of Item1 (the int) and then finding all records that have the same value.
HTH, like mentioned in the comments previously good to post what you have tried in future.
I have a list which has data
list1 [{actId: 1, dt:'10/5/2015', hr:3}, {actId: 1, dt:'10/5/2015', hr:5},
{actId: 3, dt:'10/4/2015', hr:3}, {actId: 4, dt:'10/6/2015', hr:1},
{actId: 4, dt:'10/6/2015', hr:8}, {actId: 1, dt:'10/2/2015', hr:3}]
I am using a Linq query to group the data
var dat= list1.AsEnumerable().GroupBy(t=> new{t.actId, t.dt})
.Select(x=> new
{
tId=x.Key.techId,
dat=x.Key.dt,
thrs=x.Sum(y=>y.hr)
});
This works and gives me result but gives me the results grouping both "actId" and "dt" while I want to just group them by "actId". If I change the query to
var dat= list1.AsEnumerable().GroupBy(t=> new{t.actId})
.Select(x=> new
{
tId=x.Key.techId,
dat=x.dt,
thrs=x.Sum(y=>y.hr)
});
I get intellisense error for x.dt saying "Cant Resolve Symbol "dt"
Please let me know how to change the query so I can include x.dt in it without grouping by it.
So output should look like
[ {actId:1, [{dt: 10/5/2015, hr:8}, {dt: 10/2/2015, hr:38}]},
{actId: 3, [{dt: 10/4/2015, hr:3}]},
{actId: 4 [{dt: 10/6/2015 hr: 9}]}]
Thanks
It's because there isn't a single 'dt', there is a group of them, this will return them all as a group for you:
var dat=list1.AsEnumerable()
.GroupBy(t=> t.actId)
.Select(x=> new
{
actId=x.Key,
dat=x.Select(x=>new { x.dt,x.hr}).ToList()
});
This is as close as I can get to your output. It'll look like:
[ {actId:1, dat:[{dt: 10/5/2015, hr:8}, {dt: 10/2/2015, hr:38}]},
{actId: 3, dat:[{dt: 10/4/2015, hr:3}]},
{actId: 4, dat:[{dt: 10/6/2015 hr: 9}]}]
I'm looking for a way to get multiple keys with a single value. Yes, I've already used the search function, but most answers are for the opposite direction (multiple values per key), but I want the opposite.
The reasoning behind this is that I want keep multiple Item-IDs (it's for a Bot) per "main" ID, and throwing those multiple IDs into a value of the one is too slow to modify (looking for one value => looping trough all main IDs & getting each value, then checking if that ID exists).
Example
Key 1 => Value
Key 2 => Value
Key 3 => Value
Key 4 => Value
Key 5 => Value 2
Looking for Value should return: Key 1-4, not 5
So I'm looking for a way to do that easier - like I said above.
Anyone knows if that's possible and how to do it?
Thanks in advance.
Edit:
Looking at your edit, it really looks like you have designed this Dictionary backwards... your keys should be for matching values, not your values for matching keys.
You could do something like create a dictionary that maps outer-keys to inner-keys, then use the inner-key to index a second dictionary.
Example:
var outer = new Dictionary<int, Guid> {
{ 1, GuidA },
{ 2, GuidA },
{ 3, GuidA },
{ 4, GuidA },
{ 5, GuidB }
};
var inner = new Dictionary<Guid, Value> {
{ GuidA, Value1 },
{ GuidB, Value2 }
};
You would access it as: value = outer[inner[key]].
You may be overthinking your problem. Keys need to be unique in order to be useful for lookup operations. Values do not need to be unique. Multiple keys can point to the same value without causing problems.
Do the dictionary the other way around and make the value a list of items.
if for example Value is a string and Key 1-4 are ints your dictionary could look something like:
var theDictionary = new Dictionary<string, List<int>>();
retrieving Value by theDictionary["Value"] would then return a list of ints containing 1, 2, 3 and 4.
Edit - Added example:
var theDictionary = new Dictionary<string, List<string>>
{
{"Value", new List<string> {"Key 1", "Key 2", "Key 3", "Key 4", "Key 5",}},
{"Value2", new List<string> {"Key 5", "Key 2"}}
};
var oneToFour = theDictionary["Value"];
1) Servy is absolutely correct. If you're doing a search on anything but a key ... and if you're trying to retrieve anything but the corresponding value ... then something is definitely wrong. All things being equal, you probably DON'T want a dictionary.
2) Based on what you're saying, perhaps a better collection type might be a List. Specifically, a list of name/value pairs.
EXAMPLE:
List<string> NVList = new List<string>();
NVList.Add("color=blue");
...
3) Note that .Net has a specialized "NameValueCollection" class that might be IDEAL for you:
http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx
Assuming you have your initial dictionary (mapping your keys to values) already you can use some Linq to convert it into a reverse dictionary without having to create that reverse dictionary by hand.
var newDict = initialDict.Select(x=>x.Value).Distinct().ToDictionary(x=>x, x=> initialDict.Where(kvp=>kvp.Value == x).Select(kvp=>kvp.Key));
Select the distinct originalValues from your original dictionary and use those as your newKeys. Your newValues are the set of your originalKeys that mapped to each originalValue/newKey.
Example: https://dotnetfiddle.net/dhwUSC
Given an initial dictionary of
var initialDict = new Dictionary<int, string>{
{1, "Value"},
{2, "Value"},
{3, "Value"},
{4, "Value"},
{5, "Value2"}
};
the above function returns
Value: {1, 2, 3, 4}
Value2: {5}
I have some code that currently looks somewhat like this:
Parallel.Invoke(
MyFunction1,
MyFunction2,
MyFunction3,
MyFunction4,
MyFunction5);
This works really well. Now I also have a list of bytes that's passed in as a parameter and that looks like this:
TheList = new List<Byte>{1, 3, 5, 6 };
I want to execute functions based on the content of that list. Let's say that each value of this list is associated to the execution a certain function, like this:
1: MyFunction1,
2: MyFunction2,
...
6: MyFunction6
The actual names of these functions are different.
How do I change my code so that the function calls get executed in parallel and conditionally to the content of the list of bytes? For instance, if the list contains 1 and 5 then the code will execute only MyFunction1 and MyFunction5, both in parallel.
Thanks.
How about this?
Dictionary<byte, Action> actions = new Dictionary<byte, Action>()
{
{ 1, MyFunction1 },
{ 2, MyFunction2 },
...
{ 6, MyFunction6 }
};
List<byte> actionList = new List<byte>() { 1, 3, 5, 6 };
Parallel.Invoke((from action in actionList select actions[action]).ToArray());
That's it. The question is in the title
I was looking for a cleaner way than the using for...break;
thanks
This should do it!
var items = new List<int>(){ 1, 2, 3, 4, 5 };
var results = items.Take(3);