Question

I have a class that got bloated with properties and now there's about 30 of them, most of which are integer enumerated types.

My code currently uses this in a bunch of places, and I'm trying to gently move to the new dictionary representation.

I'm looking to create a dictionary out of this object, but only include values that are non-0, (values that have some data).

Is there some objective-c key value coding magic that can help me simplify writing this method?

@property(nonatomic)kGrade grade;
@property(nonatomic)kQuality quality;
//a whole bunch more properties

    -(NSMutableDictionary*)itemAsDictionary
    {
        if(itemDictionary !=nil)
        {
            return itemDictionary;
        }else
        {
            itemDictionary = [[NSMutableDictionary alloc] initWithCapacity:40];


            //I really dont want to write a whole bunch of such statements
            if(self.grade>0)
            {
                [itemDictionary setObject:@(self.grade) forKey:@"grade"];
            }
            //add 39 other items

        }
        return itemDictionary;
    }
Was it helpful?

Solution 2

- (NSMutableDictionary *)itemAsDictionary
{
    NSMutableDictionary *resultDic = [[NSMutableDictionary alloc] init];
    unsigned int outCount, i;
    //type the name of the class you want to turn to dictionary
    objc_property_t *properties = class_copyPropertyList([Item class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if (propName) {
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            id propertyValue = [self valueForKey:propertyName];

            //set up the filter here
            if([propertyValue isKindOfClass:[NSNumber class]] && [propertyValue intValue] > 0)
            {
                [resultDic setObject:propertyValue forKey:propertyName];
            }else if(![propertyValue isKindOfClass:[NSNumber class]] && propertyValue !=nil)
            {
                //copy all non-nil variables
                [resultDic setObject:propertyValue forKey:propertyName];
            }

        }
    }
    free(properties);
    return resultDic;
}

I try to get the property list from a class and then return a dictionary, it's worked.maybe you can try it.

Edit: The code above did not work if I used [self class] in a subclass, but did work when I replaced self with [Item class].

I added a couple simple checks - I'm interested in numbers greater than 0 and non-nil properties, like strings and images. Notice that if I remove the second number check, the code will put zeros in the resulting dictionary.

OTHER TIPS

You can use dictionaryWithValuesForKeys: and then remove any entries equal to zero:

- (NSMutableDictionary *)itemAsDictionary {
    NSArray *keyArray = @[@"grade",
                          @"otherProperty"
                          // etc.
                          ];

    NSMutableDictionary *itemDictionary = [[self dictionaryWithValuesForKeys:keyArray] mutableCopy];

    NSArray *keys = [itemDictionary allKeys];

    for(NSString *key in keys) {
        NSNumber *item = itemDictionary[key];
        if(item.doubleValue == 0.0)
            [itemDictionary removeObjectForKey:key];
    }

    return itemDictionary;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top