OleB
OleB

Reputation: 618

Matrix info extraction

I am back with my converter app problems. As the internet clearly told me using if-else's for converting was bad, i tried to get data of a matrix instead. This is my attempt;

float convertFrom = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0]] floatValue];
float convertTo = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1]] floatValue];
float input = [inputText.text floatValue];
float to = convertTo;
float from = convertFrom;
float convertValue = input;


int matrix [5] [5] = {
    {1,2,3,4,5},
    {2,4,6,8,10},
    {3,6,9,12,15},
    {4,8,12,16,20},
    {5,10,15,20,25}};




NSString *MTPA = [[NSString alloc ] initWithFormat:
                         @" %i %i ", matrix [[%f][%f], from, to]];

So what i want this code to do, is to take the value of the units currently in the UIPickerWheel, use it as coordinates for what number to take from the int, and later on put in in a float for calculation. This is just a test to see if it works. Is it impossible to use float's as co-ordinates for a matrix, or am i just doin' it wrong?

Upvotes: 3

Views: 111

Answers (1)

rob mayoff
rob mayoff

Reputation: 385600

Using a matrix for unit conversions is a bad way to do this.

Pick a “fundamental unit”. For example, if you're converting units of length, pick meters as your fundamental unit.

Create a UnitDefinition struct that holds the name of a unit and the conversion factor to convert that unit to the fundamental unit:

typedef struct {
    unsigned long long toFundamentalUnitNumerator;
    unsigned long long toFundamentalUnitDenominator;
    __unsafe_unretained NSString *unitName;
} UnitDefinition;

Then create an array holding the units you want to support:

static UnitDefinition unitDefinitions[] = {
    { 1, 1000000, @"micron" },
    { 1, 1000, @"millimeter" },
    { 1, 100, @"centimeter" },
    { 1, 10, @"decimeter" },
    { 1, 1, @"meter" },
    { 10, 1, @"decameter" },
    { 100, 1, @"hectometer" },
    { 1000, 1, @"kilometer" },
    { 1000000, 1, @"megameter" },
    { 254, 10000, @"inch" },
    { 9144, 10000, @"yard" },
    { 160934, 100, @"mile" }
};

You'll also need a constant for the number of units in the array:

#define kUnitDefinitionCount (sizeof unitDefinitions / sizeof *unitDefinitions)

Now you can implement the UIPickerViewDataSource protocol like this:

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return kUnitDefinitionCount;
}

and you can implement the UIPickerViewDelegate protocol like this:

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return unitDefinitions[row].unitName;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    [self updateResultView];
}

and you can implement updateResultView like this:

- (void)updateResultView {
    UnitDefinition *fromUnit = &unitDefinitions[[unitsPicker_ selectedRowInComponent:0]];
    UnitDefinition *toUnit = &unitDefinitions[[unitsPicker_ selectedRowInComponent:1]];

    double input = inputField_.text.doubleValue;
    double result = input
        * fromUnit->toFundamentalUnitNumerator
        * toUnit->toFundamentalUnitDenominator
        / fromUnit->toFundamentalUnitDenominator
        / toUnit->toFundamentalUnitNumerator;
    resultLabel_.text = [NSString stringWithFormat:@"%.6g", result];
}

Upvotes: 3

Related Questions