2016-02-15 4 views
1

У меня есть большой объем данных, сохраненных как выход Data :: Dumper.Как организовать или прочитать большой объем данных?

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

Вот пример (очень урезанный). Кроме того, создание не было большим, поскольку персонаж может иметь две «атаки» или две «специальные», поэтому, очевидно, это столкновение, и один будет перезаписан.

EDIT: Я действительно спрашиваю: это идеальный способ хранения данных? или есть лучший способ? потому что мне доступ к хешу, как $char_hash{Character Name}{abilities}{attack}{tiers}{level 1}{description} кажется ужасно писать. и перебирая вещи, как @{$char_hash{Character Name}{Equipment}{Equipment Level 1}{Items}} кажется сумасшедшим трудно

my @char_hash = (
"Character Name" => { 
      "description" => "", 
      "alignment" => "", 
      "categories" => [ 
       "ex 1", 
       "ex 2", 
       "ex 4", 
       "ex 5" 
      ], 
      "primaryStat" => "Strength (STR)", 
      "baseStats" => { 
       "Strength (STR)" => "22", 
       "Agility (AGI)" => "15", 
       "Intelligence (INT)" => "17", 
       "Speed" => "100", 
       "Health" => "197", 
       "Physical Damage" => "17" 
      }, 
      "abilities" => { 
       "attack" => { 
        "name" => "ex 1", 
        "type" => "Physical", 
        "tiers" => { 
         "level 1" => { 
          "description" => "" 
         }, 
         "level 2" => { 
          "unlockLevel" => 16, 
          "cost" => { 
           "Money" => 700, 
           "Material" => 3 
          }, 
          "fromPrevious" => "+5% Damage", 
          "description" => "" 
         } 
        }, 
        "conditions" => { 
        } 
       }, 
       "special" => { 
        "name" => "ex", 
        "cooldown" => 3, 
        "type" => "special", 
        "tiers" => { 
         "level 1" => { 
          "description" => "" 
         }, 
         "level 2" => { 
          "unlockLevel" => 18, 
          "cost" => { 
           "Money" => 1300, 
           "Material" => 2 
          }, 
          "fromPrevious" => "+5% Damage", 
          "description" => "" 
         } 
        }, 
        "conditions" => { 
        } 
       }, 
      "Equipment" => { 
       "Equipment Lvl I" => { 
        "cummulatedStats" => { 
         "Strength (STR)" => "+22", 
         "Agility (AGI)" => "+15", 
         "Intelligence (INT)" => "+17", 
         "Speed" => "+100", 
         "Health" => "+197", 
         "Physical Damage" => "+17" 
        }, 
        "items" => [ 
         { 
          "name" => "", 
          "id" => "", 
          "tier" => 1, 
          "mark" => "", 
          "requiredLevel" => 1, 
          "sellValue" => 10, 
          "stats" => { 
           "Physical Damage" => "" 
          } 
         }, 
         { 
          "name" => "", 
          "id" => "", 
          "tier" => 1, 
          "mark" => "", 
          "requiredLevel" => 2, 
          "sellValue" => 20, 
          "stats" => { 
           "Strength (STR)" => "", 
           "Agility (AGI)" => "", 
           "Intelligence (INT)" => "" 
          } 
         }, 
         { 
          "name" => "", 
          "id" => "", 
          "tier" => 1, 
          "mark" => "", 
          "requiredLevel" => 2, 
          "sellValue" => 20, 
          "stats" => { 
           "Strength (STR)" => "", 
           "Agility (AGI)" => "", 
           "Intelligence (INT)" => "" 
          } 
         }, 
         { 
          "name" => "", 
          "id" => "", 
          "tier" => 1, 
          "mark" => "", 
          "requiredLevel" => 2, 
          "sellValue" => 20, 
          "stats" => { 
           "Speed" => "" 
          } 
         }, 
         { 
          "name" => "", 
          "id" => "", 
          "tier" => 1, 
          "mark" => "", 
          "requiredLevel" => 2, 
          "sellValue" => 20, 
          "stats" => { 
           "Strength (STR)" => "" 
          } 
         }, 
         { 
          "name" => "", 
          "id" => "", 
          "tier" => 1, 
          "mark" => "", 
          "requiredLevel" => 2, 
          "sellValue" => 20, 
          "stats" => { 
           "Armor" => "" 
          } 
         } 
        ] 
       } 
      } 
     } 
} 
); 
+1

В чем вопрос? В его нынешнем виде этот пост слишком широк, чтобы быть полезным. –

+0

I отредактировал отредактированный пост – genx1mx6

+0

Ваше редактирование почти усугубило вопрос, потому что теперь любые ответы будут скорее мнениями, чем фактами. –

ответ

3

Я бы сказал, да, есть лучший путь.

И ответ - использовать объектно-ориентированный код. OO может показаться пугающим, если вы на самом деле не столкнулись с этим - и есть много программистов на Java или C++, которым нравится это делать.

Но все это действительно есть, это структура данных, которая включает в себя код «встроенный» для управления им. Эти биты кода известны как «методы» и применяются к объекту.

Итак - взять выше. У вас есть «символы» и «оборудование» как яркие примеры «объектов».

#!/usr/bin/env perl 

package MyStuff::Character; 

use strict; 
use warnings; 

sub new { 
    my ($class, $name) = @_; 
    my $self = {}; 
    $self -> {name} = $name; 
    bless $self, $class; 
    return $self; 
} 

sub set_attr { 
    my ($self, $attr, $value) = @_; 
    $self -> {attr} -> {$attr} = $value; 
} 

sub get_attr { 
    my ($self, $attr) = @_; 
    return $self -> {attr} -> {$attr}; 
} 

sub get_name { 
    my ($self) = @_; 
    return $self -> {name}; 
} 

sub add_item { 
    my ($self, $item_ref) = @_; 
    push (@{ $self -> {items} }, $item_ref); 
} 

sub inventory { 
    my ($self) = @_; 
    return @{$self->{items}}; 
} 

package MyStuff::Items; 

sub new { 
    my ($class, $name, $type) = @_; 
    my $self = {}; 
    $self -> {name} = $name; 
    $self -> _set_type($type); 
    bless $self, $class; 
    return $self; 
} 

sub get_name { 
    my ($self) = @_; 
    return $self -> {name}; 
} 

sub _set_type { 
    my ($self, $type) = @_; 
    $self -> {type} = $type; 
    if ($type eq "sword") { 
     $self -> {attack_bonus} = "+10"; 
    } 
} 

package main; 

use strict; 
use warnings; 

my $character = MyStuff::Character -> new ("Joe Beefcake"); 
$character -> set_attr('STR', 9000); 

print $character -> get_name, " has STR ", $character -> get_attr('STR'),"\n"; 

my $new_sword = MyStuff::Character -> new ("Hackmaster", "sword"); 
$character -> add_item($new_sword); 

print "And is carrying:\n"; 
foreach my $item ($character -> inventory) { 
    print $item -> get_name,"\n"; 
} 

Это очень простой пример, но, надеюсь, иллюстрирует новый способ решения сложных структур данных?

В частности - мы «передаем» вещи, которые нам не нужны, объекту, которому нужно ухаживать, и просто используйте методы для взаимодействия с ним. Поскольку элемент является самосодержащим объектом, и он «знает» его состояние. Вы можете забрать его и «дать» его другому персонажу.

Другим преимуществом такого рода является наследование. У меня очень общий объект «item». У каждого предмета есть вещи, которые вы, возможно, захотите сделать с любым из них - забрать их, перенести, продать, передать их другому человеку.

Но вы могли бы сделать класс «оружие», который наследует класс «предмет» (и поэтому вы все равно можете дать кому-то свой меч), ​​но также добавляет лишние вещи - например, бонус атаки, бонус атаки и т. д.

Понятие ориентации объекта не является новым, но оно не слишком распространено в perl. Там есть perldoc perlobj, который имеет некоторые основы.

Существует также несколько пакетов, которые помогают процессу (вышеуказанные работы автономны), как Moose.

Для «сохранения» и «загрузки» - существует ряд возможных вариантов, и это немного зависит.

Я хотел бы , вероятно, решить его путем сериализации «символов» и «предметов» отдельно для JSON и перезагрузить/подтвердить.

Это покрыта в немного более подробно здесь: How to convert Perl objects into JSON and vice versa

+0

Хороший подход! Извините мое невежество, но где в вашем коде вы сохраняете структуры данных на диск между играми, пожалуйста? –

+0

Спасибо за помощь, я даже не думал о подходе OO. Наследие действительно приятно сейчас, когда я думаю об этом. – genx1mx6

+0

Я этого не делаю. Вышесказанное является иллюстрацией и фактически довольно широкой темой в ее собственном праве. Я, вероятно, сделаю это методом 'save' и сериализацией в' JSON'. (Например, сохраните символ и сохраните «элементы» в другой вспомогательной директории в виде отдельных файлов, которые вы «читали») – Sobrique

0

Во-первых, когда я отправил свои данные в файл и использовать команду процентов в VI, я нашел то, что я считаю, это склеивание ошибка. Как бы то ни было, хэш «способностей» состоял из трех записей, включая «Оборудование». Глядя на отступы, это очень похоже на ошибку - я считаю, что закрытие курчавого отсутствует над буквой «E» в «Оборудовании», и необходимо закрыть соответствующую фигуру (третью в файле). Затем «Оборудование» становится характеристикой персонажа, а не типа способности, которое кажется более вероятным.

После исправления этого, что вы можете сделать? Я не думаю, что есть простой выход - вам нужно расчесывать данные, ищущие повторяющиеся шаблоны, и идентифицировать группы данных, которые могут быть кандидатами на объекты.

Принимая его сверху и игнорируя детали, мы видим, что персонаж состоит из семи атрибутов - возможно, не так плохо, как кажется на первый взгляд. Я собираюсь использовать perl6 как более сжатый для деклараций классов и, откровенно говоря, с чем-то большим, любое решение является хорошим решением (или, более откровенно, я не хочу быть здесь весь день);

class Character { 
    has $.description ; 
    has $.alignment ; 
    has $.categories ; 
    has $.primaryStat ; 
    has $.baseStats ; 
    has Abilities $.abilities ; 
    has %.equipment of Equipment ; 
} 

baseStats может быть объектом в своем собственном праве, но его прямой хэш - поэтому оставьте его. Идея здесь состоит в том, чтобы создавать под-объекты только тогда, когда нам нужно из-за глубины структуры.

Глядя на abilities, их всего два; способности атаки и особые способности. Было бы лучше вывести их из своего хэш-хэша - создать еще один уровень ради двух записей. Они также имеют одинаковые атрибуты, поэтому мы можем создать под-объект Abilities и содержать два из них в нашем классе Character - один для атаки и один для специального.

Похоже, что уровни являются хешем, где находятся "level n", а значения - хэши данных уровня. Его спорный, но, вероятно, стоит создать класс для представления уровня или уровня. Итак, это занимает три уровня в глубину - опять же, возможно, не так плохо, как кажется на первый взгляд.

Оборудование выглядит похоже на уровни в том, что его хэш, где ключи являются уровнями, а значения - хэши данных. Эти данные представляют собой прямое хеш-файл под номером "cummulatedStats", а затем список элементов. Опять же, его решение, но я бы сказал, что вам нужен под-объект Item. Итак, у нас есть;

#!/usr/bin/env perl6 

class Tiers { 
    has $.unlockLevel ; 
    has $.cost ; 
    has $.fromPrevious ; 
    has $.description 
} 

class Abilities { 
    has $.name ; 
    has $.cooldown ; 
    has $.type ; 
    has %.tiers of Tiers ; 
    has $.conditions ; 
} 

class Items { 
    has $.name ; 
    has $.id ; 
    has $.tier ; 
    has $.mark ; 
    has $.requiredLevel ; 
    has $.sellValue ; 
    has $.stats ; 
} 

class Equipment { 
    has $.cummulatedStats ; 
    has $.items ; 
} 

class Character { 
    has $.description ; 
    has $.alignment ; 
    has $.categories ; 
    has $.primaryStat ; 
    has $.baseStats ; 
    has Abilities $.attack_abilities ; 
    has Abilities $.special_abilities ; 
    has %.equipment of Equipment ; 
} 

my %char_hash = hash.new(
      "description" => "", 
      "alignment" => "", 
    ... etc from your data ... 

Теперь нам нужно вытащить Abilities из их хэш для создания вложенных объектов. Нам также необходимо сделать то же самое с Tiers и Items. Этот пост уже слишком длинный, поэтому я перейду к преследованию;

my %equipment = %char_hash<Equipment> :delete ; 
my %abilities = %char_hash<abilities> :delete ; 

my %special = %abilities<special> ; 
my %attack = %abilities<attack> ; 
%abilities =(); 

for %special<tiers>.kv -> $level, $data_hash { 
    %special<tiers>{ $level } = Tiers.new: |$data_hash 
} 
for %attack<tiers>.kv -> $level, $data_hash { 
    %attack<tiers>{ $level } = Tiers.new: |$data_hash 
} 

%char_hash<special_abilities> = Abilities.new: |%special ; 
%char_hash<attack_abilities> = Abilities.new: |%attack ; 

for %equipment.kv -> $level, $data_hash is rw { 
    my @items; 
    @items.push: Items.new(|$_) for $data_hash<items>.flat ; 
    $data_hash<items> = @items ; 
    %equipment{ $level } = Equipment.new: |$data_hash ; 
} 
%char_hash<equipment> = %equipment ; 

my $char = Character.new(|%char_hash); 
say $char.perl; 

Подход наизнанку - мы начинаем с ярусов, поскольку они вложены в самую глубокую. Мы создаем хэш уровней, а затем перетаскиваем их обратно в хэш-коды %special и %attack. Из них мы можем создать два объекта Abilities и высунуть их обратно в главный хеш, %char_hash.

Аналогичным образом с Items, а затем Equipment, прежде чем мы, наконец, готовы создать наш Character. После загрузки данных вы можете создать методы строения, .Str, чтобы настроить представление каждого типа объектов.Также должно быть легко создать специальные целевые методы для манипуляций и преобразований, которые вы хотели достичь.

... Я не должен был начинать этот вопрос ;-)

Смежные вопросы