| AI-ExpertSystem-Advanced documentation | Contained in the AI-ExpertSystem-Advanced distribution. |
AI::ExpertSystem::Advanced::Dictionary - Array/hash dictionary
The dictionary offers a unified interface for:
Reading through a list of items with a minimal use of memory since it offers an iterator that works with a stack. So everytime it gets asked for the next element it drops the first or last element of the stack.
Finding an element in the stack.
Adding or removing elements from the stack.
An array with all the keys of stack_hash. Useful for creating the
iterable_array and for knowing the order of the items as they get added or
removed.
The original hash, has all the elements with all their properties (eg extra
keys). The disadvantage of it is that it doesn't keeps the order of the
elements, hence the need of stack.
Used by the iterate() and iterate_reverse() methods. It starts as a copy
of stack and as the iterate methods start running this array starts getting
reduced until it gets to an empty list.
Looks for a given value ($look_for). By default it will look for the value
by reading the id of each item, however this can be changed by passing
a different hash key ($find_by).
In case there's no match undef is returned.
The AI::ExpertSystem::Advanced::Dictionary consists of a hash of elements, each element has its own properties (eg, extra keys).
This method looks for the value of the given $key of a given element id.
It will return the value, but if element doesn't have the given $key then
undef will be returned.
Adds a new element to the stack_hash and stack. The element gets added to
the end of stack.
The $id parameter specifies the id of the new element and the next parameter
is a stack of extra keys.
Same as append(), but the element gets added to the top of the stack.
Updates the extra keys of the element that matches the given $id.
Please note that it will only update or add new keys. So if the given element
already has a key and this is not provided in %extra_keys then it wont
be modified.
Removes the element that matches the given $id from stack_hash and
stack.
Returns true if the removal is successful, otherwise false is returned.
Returns the size of stack.
Returns the first element of the iterable_array and iterable_array is
reduced by one.
If no more items are found in iterable_array then undef is returned.
Same as iterate(), but instead of returning the first element, it returns
the last element of iterable_array.
The iterable_array gets populated when a dictionary instance is created,
however if new items are added or removed then it's extremely needed to call
this method so iterable_array gets populated again.
Pablo Fischer (pablo@pablo.com.mx).
Copyright (C) 2010 by Pablo Fischer.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| AI-ExpertSystem-Advanced documentation | Contained in the AI-ExpertSystem-Advanced distribution. |
# # AI::ExpertSystem::Advanced::Dictionary # # Author(s): Pablo Fischer (pfischer@cpan.org) # Created: 11/29/2009 20:06:22 CST 20:06:22 package AI::ExpertSystem::Advanced::Dictionary;
use Moose; use List::MoreUtils qw(firstidx); our $VERSION = '0.03';
has 'stack' => ( is => 'rw', isa => 'ArrayRef');
has 'stack_hash' => ( is => 'ro', isa => 'HashRef[Str]');
has 'iterable_array' => ( is => 'ro', isa => 'ArrayRef');
sub find { my ($self, $look_for, $find_by) = @_; if (!defined($find_by)) { if (defined $self->{'stack_hash'}->{$look_for}) { return $look_for; } return undef; } foreach my $key (keys %{$self->{'stack_hash'}}) { if ($self->{'stack_hash'}->{$key}->{$find_by} eq $look_for) { return $key; } } return undef; }
sub get_value { my ($self, $id, $key) = @_; if (!defined $self->{'stack_hash'}->{$id}) { return undef; } if (defined $self->{'stack_hash'}->{$id}->{$key}) { return $self->{'stack_hash'}->{$id}->{$key}; } else { return undef; } }
sub append { my $self = shift; my $id = shift; return $self->_add($id, undef, @_); }
sub prepend { my $self = shift; my $id = shift; return $self->_add($id, 1, @_); }
sub update { my ($self, $id, $properties) = @_; if (defined $self->{'stack_hash'}->{$id}) { foreach my $key (keys %$properties) { $self->{'stack_hash'}->{$id}->{$key} = $properties->{$key}; } } else { warn "Not updating $id, does not exist!"; } }
sub remove { my ($self, $id) = @_; if (defined $self->{'stack_hash'}->{$id}) { delete($self->{'stack_hash'}->{$id}); # Find the index in the array, lets suppose our arrays are big my $index = List::MoreUtils::first_index { defined $_ and $_ eq $id } @{$self->{'stack'}}; splice(@{$self->{'stack'}}, $index, 1); return 1; } return 0; }
sub size { my ($self) = @_; return scalar(@{$self->{'stack'}}); }
sub iterate { my ($self) = @_; return shift(@{$self->{'iterable_array'}}); }
sub iterate_reverse { my ($self) = @_; return pop(@{$self->{'iterable_array'}}); }
sub populate_iterable_array { my ($self) = @_; @{$self->{'iterable_array'}} = @{$self->{'stack'}}; } # No need to document it, used by L<Moose>. sub BUILD { my ($self) = @_; foreach (@{$self->{'stack'}}) { if (ref($_) eq 'ARRAY') { $self->{'stack_hash'}->{$_->[0]} = { name => $_->[0], sign => $_->[1] }; } else { $self->{'stack_hash'}->{$_} = { name => $_, sign => '+' }; } } $self->populate_iterable_array(); } ################# Private methods ###################### sub _add { my ($self, $id, $prepend, $properties) = @_; $self->{'stack_hash'}->{$id} = $properties; if ($prepend) { unshift(@{$self->{'stack'}}, $id); } else { push(@{$self->{'stack'}}, $id); } }
1;