Home > Software design >  How would you divide all the negative values in a dictionary in C#?
How would you divide all the negative values in a dictionary in C#?

Time:11-25

I have a Dictionary<string, double>. I looped through the values to remove all the positive double values.

I need to divide the remaining negative values together and then round it to 10 decimal points.

double divisionSum = 1;
foreach (var entry in dic.Values)
{
    divisionSum /= entry;
}

This doesn't work as 1 divided by a negative number does not return it's initial value for the first instance of division.

For example, if the values of the Dictionary was -2, -4, -8, -5 I would want divisionSum to equal 0.0125. Also cannot use any Math() methods

CodePudding user response:

Loop through your list (ok, it's a dictionary, but you only care about the values, so it's basically a list) starting at index 1 not the default of 0, but first assign the value of index 0 to your result.

var foo = new List<double>{-1, -10, -3, -5};

double result = foo[0];
for (int i = 1; i < foo.Count; i  )
{
    result /= foo[i];
}

result = Math.Round(result, 10);
result.Dump();

CodePudding user response:

It works if you start with the first value instead of 1. To have better control on accessing individual value, I have converted the values from the dictionary into an array:

double[] values = dic.Values.ToArray();
double divisionSum = values[0];
for (int i = 1; i < values.Length; i  ) {
    divisionSum /= values[i];
}
// divisionSum => 0.0125

Note that the for-loop starts at index 1 to skip the first value at index 0 which was already assigned to divisionSum.

The advantage of a dictionary is that you can look up values very quickly by key. They are not particularly good when you have to loop over the values. It would be better to use a list or array for this purpose.

CodePudding user response:

The following corrects the code so that divisionSum is initialised with the first value and the loop divides in the remaining values. The last line does the rounding to 10 decimal places without using any Math() methods, which was a requirement.

var valuesList = dic.Values.ToList();
var divisionSum = valuesList[0];

for (var index = 1; index < valuesList.Count; index  )
{
    divisionSum /= valuesList[index];
}

divisionSum = Convert.ToDouble(divisionSum.ToString("#.0000000000", CultureInfo.InvariantCulture));

CodePudding user response:

You can query the dictionary with a help of Linq:

using System.Linq;

...

// Let me keep the name; result looks a better however
double divisionSum = dic
  .Values
  .Where(item => item < 0)      
  .DefaultIfEmpty(0.0)          // put the default value here: 0, 1 or whatever 
  .Aggregate((s, a) => s / a);

For no Linq solution we have to initialize within the loop (let's have firstTime flag) with the 1st negative item:

double divisionSum = 0.0; // put default value here: 0, 1 or whatever
bool firstTime = true;

foreach (var item in dic.Values) {
  if (item < 0) {
    divisionSum = firstTime ? item : divisionSum / item;

    firstTime = false; 
  }
}
  • Related