0

I've List Tuple with int and string in it, each time I add new position to this list, I check for the same string in already added elements. Once I see the same - the goal is to change int (to do +1). For example if we have (3, box; 1, apple; 2, PC) and we need to add "apple", so I must change existing "1, apple" to "2, apple". But I can't do it because Item1 return error "The property has no setter". Where my mistake? Thanks.

        string[] elements = s.Split(); // Contains all elements as strings.

        List<Tuple<int, string>> elementsList = new List<Tuple<int, string>>();

        var sortItems = elementsList.OrderBy(x => x.Item1);

        for (int i = 0; i < elements.Length; i++)
        {
            foreach (var item in sortItems)
            {
                if (Equals(item.Item1, elements[i]))
                {
                    item.Item1 += 1;
                }
            }
            elementsList.Add(new Tuple<int, string>(1, elements[i]));
        }         
        return elementsList;
Jack
  • 71
  • 2
  • 5
  • 4
    Do you have to use `List>`? I think your code would be a lot simpler if you went with `Dictionary` for this purpose. – CoolBots May 12 '16 at 06:18
  • A more nice approach is `var list = elements.GroupBy(e => e).Select(g => Tuple.Create(g.Count(), g. Key)).ToList();` or similar. – Jeppe Stig Nielsen May 12 '16 at 06:28
  • Agree with @CoolBots comment, generic `Dictionary` is what you exactly need, because it is based on hash table, thus the search in dictionary will be much faster than in `List` – Ihor Korotenko May 12 '16 at 06:38

4 Answers4

9

According to the documentation of Tuple<T1,T2>, the properties cannot be written, which basically means that tuples are immutable. It is impossible to modify its contents in-place; it is necessary to create a new tuple.

Codor
  • 17,447
  • 9
  • 29
  • 56
1

Tuple<T1, T2> does not allow you to modify the values inside because it is immutable. Instead try using a Dictionary

string[] elements = s.Split(); // Contains all elements as strings.

IDictionary<string, int> elementsMap = new Dictionary<string, int>();

for (int i = 0; i < elements.Length; i++)
{
    string name = elements[i];

    if (elementsMap.ContainsKey(name))
    {
        elementsMap[name] += 1;
    }
    else
    {
        elementsMap.Add(name, 1);
    }
}
return elementsMap;

Or through Linq(credit to Jeppe Stig Nielsen):

var elementsMap = elements.GroupBy(e => e).ToDictionary(g => g.Key, g => g.Count());
Bijington
  • 3,661
  • 5
  • 35
  • 52
1

Tuples are immutable types, so basically they are not intented to be changed and have no setter. The reasons got listed up here : Why Tuple's items are ReadOnly?

Either you create a new tuple (as Codor suggested) or you just create your own implementation, like shown here: Why a Tuple, or a KeyValueItem, don't have a setter?

Community
  • 1
  • 1
Noires
  • 643
  • 8
  • 19
0

Tuple class is immutable which means its properties do no have public setters to overwrite the underlying value.

Tuples are not meant to be used in a key-value manner, which is probably closer to what you are trying to achieve. Tuples are more suitable for pairing - well they are could be used for more than 2 practically - two correlated pieces of data, such as coordinates for example, or width and height.

More examples in the answers of the link below :

Practical example where Tuple can be used in .Net 4.0?

When should you use a Dictionary ?

Simply when you are doing lookups by a certain unique key to read/modify the an object(which could be a collection it self) corresponding to that key. a quick google around would show you tons of uses.

Community
  • 1
  • 1
sm_
  • 2,572
  • 2
  • 17
  • 34