jxbma
asked on
How do I iterate over a List<KeyValuePair<>> and update the value of my KeyValuePair<>?
I have a List<T> defined below.
========================== ========== ========== ========== ===
List<KeyValuePair<MyClass, decimal>> tciList = new List<KeyValuePair<MyClass, decimal>>();
int myValue = 12;
This is an in memory list, and I'd like to update values based on a selection criteria.
Currently, I can write a LINQ query that returns all the values based on that criteria.
TAKE #1:
-----------
foreach (var item in from v in tciList .AsEnumerable()
where (v.Key as MyClass).DiscountID == (int)myValue
select v)
{
item.Value = 100;
}
TAKE #2:
-----------
foreach (KeyValuePair<MyClass, decimal>item in tciList.AsEnumerable())
{
item.Value = 100;
}
In either case, I get the following error:
========================== ========== ========== ========== ========== =========
Error 404
Property or Indexer
'System.Collections.Generi c.KeyValue Pair<Explo rica.Sales .Business. TravelerTo urCenterIn formation, decimal>.V alue'
cannot be assigned to -- it is read only
========================== ========== ========== ========== ========== =========
What's going on here? Is there a copy of the list get returned for the iteration?
I googled and saw reference to some changes between Beta 2 and Beta 3 which after which folks started
encountering the error.
How do I iterate over the list and make changes to values in my KeyValuePair<>?
Thanks,
JohnB
==========================
List<KeyValuePair<MyClass,
int myValue = 12;
This is an in memory list, and I'd like to update values based on a selection criteria.
Currently, I can write a LINQ query that returns all the values based on that criteria.
TAKE #1:
-----------
foreach (var item in from v in tciList .AsEnumerable()
where (v.Key as MyClass).DiscountID == (int)myValue
select v)
{
item.Value = 100;
}
TAKE #2:
-----------
foreach (KeyValuePair<MyClass, decimal>item in tciList.AsEnumerable())
{
item.Value = 100;
}
In either case, I get the following error:
==========================
Error 404
Property or Indexer
'System.Collections.Generi
cannot be assigned to -- it is read only
==========================
What's going on here? Is there a copy of the list get returned for the iteration?
I googled and saw reference to some changes between Beta 2 and Beta 3 which after which folks started
encountering the error.
How do I iterate over the list and make changes to values in my KeyValuePair<>?
Thanks,
JohnB
Try something like this:
var tmpList = new List<KeyValuePair<Test, decimal>>();
tmpList.Add(new KeyValuePair<Test,decimal>(new Test(){ Val1="a" }, 100));
tmpList.Add(new KeyValuePair<Test, decimal>(new Test() { Val1 = "b" }, 200));
tmpList.Add(new KeyValuePair<Test, decimal>(new Test() { Val1 = "c" }, 300));
tmpList.Add(new KeyValuePair<Test, decimal>(new Test() { Val1 = "d" }, 400));
tmpList.Add(new KeyValuePair<Test, decimal>(new Test() { Val1 = "e" }, 600));
for (int i = 0; i < tmpList.Count; i++)
{
var newKvp = new KeyValuePair<Test, decimal>(tmpList[i].Key, 100);
tmpList.RemoveAt(i);
tmpList.Insert(i, newKvp);
}
ASKER
Hi kaufmed:
When I attempted your suggestion, I get this additional error:
-------------------------- ---------- ---------- ---------- ---------- ---------- --------
Error 457
The best overloaded method match for
'System.Collections.Generi c.List<Sys tem.Collec tions.Gene ric.KeyVal uePair<MyC lass,decim al>>.this[ int]' has some invalid arguments
So, I swapped out the and tried iterating via an index.
At that pointm, it still gives the same error that I encountered.
Do I actually have to remove/add a new list item whenever I want to update my values in a List<KeyValuePair<>>?
That seems a little long winded/obscure to have to do that.
There must be a straight forward to do this...?
Thanks,
JohnB
When I attempted your suggestion, I get this additional error:
--------------------------
Error 457
The best overloaded method match for
'System.Collections.Generi
So, I swapped out the and tried iterating via an index.
At that pointm, it still gives the same error that I encountered.
Do I actually have to remove/add a new list item whenever I want to update my values in a List<KeyValuePair<>>?
That seems a little long winded/obscure to have to do that.
There must be a straight forward to do this...?
Thanks,
JohnB
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hi jxbma;
You could create your own class to represent the Key, Value Pair, See code snippet for an example.
Fernando
You could create your own class to represent the Key, Value Pair, See code snippet for an example.
Fernando
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<KVP> tciKVPList = new List<KVP>();
private void Form1_Load(object sender, EventArgs e)
{
tciKVPList.Add(new KVP() { Key = new MyClass() { myClassValue = 1, DiscountID = 2 }, Value = 1 });
tciKVPList.Add(new KVP() { Key = new MyClass() { myClassValue = 2, DiscountID = 10 }, Value = 2 });
tciKVPList.Add(new KVP() { Key = new MyClass() { myClassValue = 3, DiscountID = 3 }, Value = 10 });
tciKVPList.Add(new KVP() { Key = new MyClass() { myClassValue = 4, DiscountID = 10 }, Value = 10 });
}
private void button1_Click(object sender, EventArgs e)
{
//================================================================
// From The last question
int myDiscountID = 10;
int count = (from v in tciKVPList.AsEnumerable()
where (v.Key as MyClass).DiscountID == myDiscountID
select v).Count();
Console.WriteLine("Count = " + count);
//================================================================
// Your TAKE #1:
int myValue = 3;
foreach (KVP item in from v in tciKVPList.AsEnumerable()
where (v as KVP).Key.DiscountID == (int)myValue
select v)
{
item.Value = 100;
}
Console.WriteLine("All values that meet the test have been modified to value 100");
//================================================================
// Your TAKE #2:
foreach (KVP item in tciKVPList.AsEnumerable())
{
item.Value = 100;
}
Console.WriteLine("All values have been modified to value 100");
}
}
public class MyClass
{
public int myClassValue { get; set; }
public int DiscountID { get; set; }
}
// This class represents the Key, Value Pair.
public class KVP
{
public MyClass Key { get; set; }
public decimal Value { get; set; }
}
ASKER
Right on track. I've used it several times.
Open in new window