I need to create pairs / triples of something and store it somewhere. How can I do it?
I tried:
for (int i = 0; i < 100; i++)
{
var item=new { a=i , b="lala" ,c=4.5m}; //anonymous type
}
But then I thought: List<what>?
I could use dynamic but I want Intellisense.
(I could have also use Tuple<int,string,decimal> but if I already have what I need (=new { a=i , b="lala" ,c=4.5m};), why should I use other type (tuple)? )
Is there any solution to this?
You can use type inference
var items = Enumerable.Range(0,100)
.Select(i => new { a=i , b="lala", c=4.5m })
.ToList(); // not necessary (you can use IEnumerable)
Not sure, how you fill fields within for, but could you try:
var lstOfSmth = Enumerable.Range(0, 100)
.Select(i => new { a = i, b = "lala", c = 4.5m })
.ToList();
why should I use other type (tuple)
Because they have been designed exactly for this purpose. If you're afraid of verbose code, the using directive comes to the rescue, too.
using myPair = Tuple<int,string>;
using myTriple = Tuple<int,string,decimal>;
//...
for (int i = 0; i < 100; i++)
{
myPair pair = new myPair(1,"string");
myTriple triple = new myTriple(i,"lala", 4.5);
}
Related
Trying to iterate through a session key I have, collect the values into a list, and then compare it to a database.
I have tried:
List<Model> listVar = new List<Model>();
for(int i = 0; i < ids.Count; i++)
{
int index = arrayValue[i]
listVar = databasemodel.table.Where(s => s.id == index).ToList()
}
It's only grabbing one of the values though when I do this, kinda new to Linq. Is there a method I can use instead of what I am doing now?
I had a simlar issue before, I used the .Contains() method.. as follows:
.Where(s => id.Contains(s.id));
That should work.
Supposing the s.id is an integer then you need to add the results of your WHERE expression to the final list
var selectedids = new List<int>();
for(int i = 0; i < ids.Count; i++)
{
int index = arrayValue[i];
selectedIds.AddRange(databasemodel.table.Where(s => s.id == index));
}
Why an IEnumerable is not adding items?
this code add itens to "values" list:
List<String> values = new List<String>();
for (int i = 0; i < ddlTransportadora.Items.Count; i++)
{
values.Add(ddlTransportadora.Items[i].Value);
}
but this code makes the loop, and after values doesn't have itens:
IEnumberable<String> values = new List<String>();
for (int i = 0; i < ddlTransportadora.Items.Count; i++)
{
values.Add(ddlTransportadora.Items[i].Value);
}
Any idea?
Because the Add method defined in IList<T> interface, and IEnumerable<T> doesn't inherit from IList<T>.You can use this instead:
IList<String> values = new List<String>();
for (int i = 0; i < ddlTransportadora.Items.Count; i++)
{
values.Add(ddlTransportadora.Items[i].Value);
}
All of these will give you an IEnumerable<string>:
You can use an explicit constructor to build and populate your collection:
new List<String>( ddlTransportadora.Items.Select( x => x.Value ) )
You can use LINQ to create an enumerable collection on the fly:
ddlTransportadora.Items.Select( x => x.Value ).ToList()
ddlTransportadora.Items.Select( x => x.Value ).ToArray()
You can even skip creating an actual collection and simply use LINQ deferred execution to provide an enumerable view of your data:
ddlTransportadora.Items.Select( x => x.Value )
Why try to make things any more complicated than they need to be?
I have class like:
class SortNode
{
public Int32 m_valRating = 0;
public SortNode(Int32 valRating)
{
this.m_valRating = valRating;
}
}
and some list refSortNodeList:
List<SortNode> refSortNodeList = new List<SortNode>();
Random refRandom = new Random();
for (int i = 0; i < 100; ++i)
{
refSortNodeList.Add(new SortNode(refRandom.Next(-10, 30)));
}
foreach (var varSortNode in refSortNodeList)
{
Console.WriteLine("SortNode rating is {0}", varSortNode.m_valRating);
}
How to sort easily my refSortNodeList by m_valRating field? Or maybe I need to use some another List class?
list.Sort((x,y) =>
x.m_valRating.CompareTo(y.m_valRating));
In-place:
refSortNodeList.Sort(
(x, y) =>
x == null ? (y == null ? 0 : -1)
: (y == null ? 1 : x.m_valRating.CompareTo(y.m_valRating))
);
Creating a new enumeration:
var newEnum = refSortNodeList.OrderBy(x => x.m_valRating);
Creating a new list:
var newList = refSortNodeList.OrderBy(x => x.m_valRating).ToList();
In-place is fastest and most memory efficient, but no good if you want to also retain the old list.
The next is faster than the last and gives results as they go, but you have to re-do the sort to use it again, in which case the third is the one to go for.
Use Linq order by.
var mySortedList = refSortNodeList.OrderBy(x => x.m_valRating);
Here is a real live example where I am pulling a list from a database but it is exactly the same concept.
vendorProducts = (from vp in db.COMPANIES_VND_PRODUCTS
join p in db.CT_CT_INV_CLASSES on vp.CLASS_ID equals p.CLASS_ID
join m in db.CT_CT_MODALITY_CODES on vp.MODALITY_ID equals m.MODALITY_ID
where vp.COMPANY_ID == companyId
select new ProductTypeModality
{
Active = p.ACTIVE.Equals("Y") ? true : false,
BioMedImaging = p.BIOMED_IMAGING,
Code = p.CLASS_CODE,
Description = p.DESCRIPTION,
Id = p.CLASS_ID,
PricingMargin = p.PRICING_MARGIN,
ModalityCode = m.MODALITY_CODE,
ModalityId = m.MODALITY_ID,
VendorId = companyId
}).OrderBy(x => x.Code).ToList<ProductTypeModality>();
Implement IComparable<T>
You can use Linq for basic sorts:
refSortNodeList.OrderBy(n => n.m_valRating);
If you need more complex sorting your will need to implement IComparable to use the built in sorting.
Try this:
refSortNodeList.Sort(new delgate(SortNode x, SortNode y)
{
return x.CompareTo(y);
}
);
It's easy using linq:
var newlist = refSortNodeList.sort( n => n.m_valRating );
List<SortNode> refSortNodeList = new List<SortNode> ();
Random refRandom = new Random ();
for (int i = 0; i < 100; ++i) {
refSortNodeList.Add (new SortNode (refRandom.Next (-10, 30)));
}
// Use this (Linq) if you're using .NET 3.5 or above.
var sortedList = refSortNodeList.OrderBy (node => node.m_valRating);
foreach (var varSortNode in sortedList) {
Console.WriteLine ("SortNode rating is {0}", varSortNode.m_valRating);
}
// Use this otherwise (e.g. .NET 2.0)
refSortNodeList.Sort (
delegate (SortNode n1, SortNode n2) {
return n1.m_valRating.CompareTo (n2.m_valRating);
}
);
foreach (var varSortNode in refSortNodeList) {
Console.WriteLine ("SortNode rating is {0}", varSortNode.m_valRating);
}
Say I have a
List<double[]> x = new List<double[]>();
double[] item = new double[] {1.0,2.0,3.0};
x.add(item);
etc...
Is there a faster/cleaner way to get this into a double[,] then looping it:
double[,] arr = new double[x.Count,3];
for (row = 0; row < x.Count; row++)
{
for (col = 0; col < 3; col++)
arr[row,col] = x[row][col];
}
Thanks.
No, there isn't.
Multi-dimensional arrays are strange beasts and are not widely accepted or used in the BCL.
They're also slow and should be avoided where possible.
Because I felt like it, I solved this using LINQ, however, it's hardly any cleaner. In fact, I'd argue it's less clear, but it'd danm neat :)
// Input
List<double[]> a = new List<double[]>() {
new double[]{ 1.0, 2.0, 3.0 },
new double[]{ 4.0, 5.0, 6.0 },
new double[]{ 7.0, 8.0, 9.0 }
};
// Output
var b = a.Select((item, index) => new
{
Items = item.Select((inner, inIndex) => new { Inner = inner, Y = inIndex }),
X = index
})
.SelectMany(item => item.Items, (i, inner) => new { Value = inner.Inner, X = i.X, Y = inner.Y })
.Aggregate(new double[a.Count, a.Max(aa => aa.Length)], (acc, item) => { acc[item.X, item.Y] = item.Value; return acc; })
Note: This also works for arbitrarily sized inner double[] arrays, but there will be empty spots.
So yes, there's another way of doing it, but it's not a better way :)
There is always the var_export function?
I have a query that sums and aggregates alot of data something like this:
var anonType = from x in collection
let Cars = collection.Where(c=>c.Code == "Cars")
let Trucks = collection.Where(c=>c.Code == "Trucks")
select new {
Total = collection.Sum(v=>v.Amount),
CarValue = Cars.Sum(v=>v.Amout),
TruckValue = Trucks.Sum(v=>v.Amount),
CarCount = Cars.Count(),
TruckCount = Trucks.Count()
};
I find it really weird that I have to declare the range variable x, especially if I'm not using it. So, am I doing something wrong or is there a different format I should be following?
I could be wrong, but from your usage, I don't think you want to do a traditional query expression syntax query with your collection anyway, as it appears you are only looking for aggregates. The way you have it written, you would be pulling multiple copies of the aggregated data because you're doing it for each of the items in the collection. If you wished, you could split your query like this (sample properties thrown in)
var values = collection.Where(c => c.Code == "A");
var anonType = new
{
Sum = values.Sum(v => v.Amount),
MinimumStartDate = values.Min(v => v.StartDate),
Count = values.Count()
};
You declare a range variable no matter the looping construct:
foreach(var x in collection)
or
for(var index = 0; index < collection.Count; index++)
or
var index = 0;
while(index < collection.Count)
{
//...
index++;
}
Queries are no different. Just don't use the variable, it doesn't hurt anything.
So, am I doing something wrong?
Your query is not good. For each element in the collection, you are enumerating the collection 5 times (cost = 5*n^2).
Is there a different format I should be following?
You could get away with enumerating the collection 5 times (cost = 5n).
IEnumerable<X> cars = collection.Where(c => c.Code == "Cars");
IEnumerable<X> trucks = collection.Where(c => c.Code == "Trucks");
var myTotals = new
{
Total = collection.Sum(v => v.Amount),
CarValue = cars.Sum(v => v.Amount),
TruckValue = trucks.Sum(v => v.Amount,
CarCount = cars.Count(),
TruckCount = trucks.Count()
};