Храня пользовательские объекты в NSMutableArray в NSUserDefaults

Используйте unstack для изменения формы, поэтому возможно деление на строки, последнее изменение формы назад на stack .

Последний для правильного упорядочения использовать swaplevel , sort_index и последний reindex .

df1 = df.unstack(0)
df1.loc['% Completed', :] = df1.loc['Complete', :] / df1.loc['Total', :]
vals = ['Complete','Total','% Completed']
df1 = df1.stack().swaplevel(0,1).sort_index().reindex(vals, level=1)
print (df1)
                         June        July      August  September
Tasks Des                                                       
A     Complete      33.000000   10.000000    0.000000   0.000000
      Total        181.000000   85.000000   69.000000  15.000000
      % Completed    0.182320    0.117647    0.000000   0.000000
B     Complete       5.000000    9.000000    0.000000   1.000000
      Total         13.000000   12.000000    5.000000   1.000000
      % Completed    0.384615    0.750000    0.000000   1.000000
C     Complete      66.000000   54.000000   27.000000  12.000000
      Total        137.000000   89.000000   78.000000  22.000000
      % Completed    0.481752    0.606742    0.346154   0.545455
D     Complete     451.000000  127.000000   87.000000  28.000000
      Total        629.000000  203.000000  174.000000  51.000000
      % Completed    0.717011    0.625616    0.500000   0.549020
E     Complete      46.000000   27.000000   29.000000   2.000000
      Total        135.000000  100.000000   86.000000  24.000000
      % Completed    0.340741    0.270000    0.337209   0.083333

Другое решение с выбором DataFrame.xs , делением и созданием уровня MultiIndex по assign и set_index :

df1 = (df.xs('Complete', level=1)
        .div(df.xs('Total', level=1))
        .assign(Des='% Completed')
        .set_index('Des', append=True)
        )

vals = ['Complete','Total','% Completed']
df1 = df.append(df1).sort_index().reindex(vals, level=1)

101
задан Community 23 May 2017 в 12:09
поделиться

5 ответов

Для загрузки пользовательских объектов в массиве это - то, что я раньше захватывал массив:

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
if (dataRepresentingSavedArray != nil)
{
    NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
    if (oldSavedArray != nil)
        objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
    else
        objectArray = [[NSMutableArray alloc] init];
}

необходимо проверить, что данные, возвращенные из пользовательских значений по умолчанию, не являются нолем, потому что я полагаю, что разархивирование от ноля вызывает катастрофический отказ.

Архивация проста, с помощью следующего кода:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"];

Как f3lix указанный, необходимо заставить пользовательский объект соответствовать протоколу NSCoding. Добавление методов как следующее должно добиться цели:

- (void)encodeWithCoder:(NSCoder *)coder;
{
    [coder encodeObject:label forKey:@"label"];
    [coder encodeInteger:numberID forKey:@"numberID"];
}

- (id)initWithCoder:(NSCoder *)coder;
{
    self = [super init];
    if (self != nil)
    {
        label = [[coder decodeObjectForKey:@"label"] retain];
        numberID = [[coder decodeIntegerForKey:@"numberID"] retain];
    }   
    return self;
}
177
ответ дан Brad Larson 24 November 2019 в 04:41
поделиться

Я думаю, что похоже, что проблема с Вашим кодом не сохраняет массив результатов. Его загрузка данных пытается использовать

lastResults = [prefs arrayForKey:@"lastResults"];

, Это возвратит массив, указанный ключом.

0
ответ дан Gcoop 24 November 2019 в 04:41
поделиться

См., "Почему NSUserDefaults не удалось сохранить NSMutableDictionary в iPhone SDK?" (, Почему NSUserDefaults не удалось сохранить NSMutableDictionary в iPhone SDK? )

<час>

, Если Вы хотите к (de), сериализируют пользовательские объекты, необходимо обеспечить, функции к (de) сериализируют данные (протокол NSCoding). Решение, которое Вы отсылаете к работам с международным массивом, потому что массив не является объектом, а непрерывным блоком памяти.

0
ответ дан Community 24 November 2019 в 04:41
поделиться

Я рекомендовал бы против попытки сохранить материал как это в дб значений по умолчанию.

SQLite довольно легко взять и использовать. У меня есть эпизод в одном из моих скринкастов ( http://pragprog.com/screencasts/v-bdiphone ) о простой обертке, которую я записал (можно получить код, не покупая SC).

Это намного более чисто, чтобы хранить данные приложения в пространстве приложения.

Все, что сказало, имеет ли все еще смысл помещать эти данные в дб значений по умолчанию, затем см. сообщение f3lix отправленный.

0
ответ дан Bill Dudney 24 November 2019 в 04:41
поделиться

Я думаю, что вы получили ошибку в вашем методе initWithCoder, по крайней мере в предоставленном коде, который вы не возвращаете «Я» объект.

- (id) initWithCoder: (NSCoder *)coder
{
    if (self = [super init])
    {
        self.locationId = [coder decodeObjectForKey:@"locationId"];
        self.companyName = [coder decodeObjectForKey:@"companyName"];
        self.addressLine1 = [coder decodeObjectForKey:@"addressLine1"];
        self.addressLine2 = [coder decodeObjectForKey:@"addressLine2"];
        self.city = [coder decodeObjectForKey:@"city"];
        self.postcode = [coder decodeObjectForKey:@"postcode"];
        self.telephoneNumber = [coder decodeObjectForKey:@"telephoneNumber"];
        self.description = [coder decodeObjectForKey:@"description"];
        self.rating = [coder decodeObjectForKey:@"rating"];
        self.priceGuide = [coder decodeObjectForKey:@"priceGuide"];
        self.latitude = [coder decodeObjectForKey:@"latitude"];
        self.longitude = [coder decodeObjectForKey:@"longitude"];
        self.userLatitude = [coder decodeObjectForKey:@"userLatitude"];
        self.userLongitude = [coder decodeObjectForKey:@"userLongitude"];
        self.searchType = [coder decodeObjectForKey:@"searchType"];
        self.searchId = [coder decodeObjectForKey:@"searchId"];
        self.distance = [coder decodeObjectForKey:@"distance"];
        self.applicationProviderId = [coder decodeObjectForKey:@"applicationProviderId"];
        self.contentProviderId = [coder decodeObjectForKey:@"contentProviderId"];
    }

    return self; // this is missing in the example above


}

Я использую

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:results];
[prefs setObject:data forKey:@"lastResults"];

и

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"lastResults"];
if (dataRepresentingSavedArray != nil)
{
        NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
        if (oldSavedArray != nil)
                objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
        else
                objectArray = [[NSMutableArray alloc] init];
}

, и он прекрасно работает для меня.

С уважением,

Стефан

13
ответ дан 24 November 2019 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: