How to calculate running total of array elements? - arrays

I'm working in Rails 3.1 as a relative noob, and have managed to extract user Transaction amounts from the db into a date-ordered array using this code (where date and amount_cents are db attributes):
#user_trans = User.transactions.order("date").map {|t| t.amount_cents}
=> [1000, -350, -250, 600, 750, -450]
I easily get a total of the array with:
#user_trans.sum => 1300
But what I just can't figure out is an elegant way to iterate over each element of the array and add the first element to the second, second to third, etc., resulting in running totals:
[1000, 650, 400, 1000, 1750, 1300]
It seems that .each or .inject would be the method used, but outside of a clunky multi-line hack, I haven't found the magic syntax to do this, but it seems there should be a streamlined approach. Order IS important. Maybe regress off the total, then reverse?
I sit at your feet with hopeful expectation... :)

Here's a one-liner. The to_i is necessary to handle the first element where the result array is empty (nil.to_i will evaluate to 0).
#user_trans.inject([]) { |result, element| result << result.last.to_i + element }

Related

Document each element of an array using spring-restdocs

I'm having a response which is an json array. Each element has it's meaning and I would be able to describe it.
My array:
["1525032694","300","true"]
I've found an example in the documentation that describes an array and each element which is the same:
https://docs.spring.io/spring-restdocs/docs/current/reference/html5/#documenting-your-api-request-response-payloads-fields-reusing-field-descriptors
But I would like to know how I can describe each of it as:
current timestamp, seconds to next measurement, should perform fota
My current test:
webTestClient.post().uri("/api//measurement/${SampleData.deviceId}")
.syncBody(SampleData.sampleMeasurement())
.exchange()
.expectStatus()
.isOk
.expectBody()
.consumeWith(document("add-measurement", responseFields(
fieldWithPath("[]")
.description("An array of device settings"))
))
Ok, it turns that be fairly easy:
responseFields(
fieldWithPath("[0]").description("Current timestamp"),
fieldWithPath("[1]").description("Device mode"),
fieldWithPath("[2]").description("Device parameter")
),

Collecting elements in a list while iterating a collection in a thread-safe way

I set Salesforce fetchSize=100 but it does not fetch elements in sets of 100 for my query. Therefore I want to be able to collect the single result from the ConsumerIterator into a list, to be handed off to a batch process in sets of 100. Here is the code below. Is this a correct way to do it? I would appreciate any suggestions on how to do it correctly. I would like to process all the ConsumerIterator elements in batches of 50. If the batch is less than 50, I would like to process that batch. My attempt is below
ConsumerIterator<HashMap<String,Object>> iter=
(ConsumerIterator<HashMap<String,Object>>)obj;
List<HashMap<String,Object>> l=new CopyOnWriteArrayList<>();
while(iter.hasNext()){
Object payload=iter.next();
if(l.size()<50){
l.add((HashMap<String,Object>)payload);
}else{
write(l);
}
public int [] write(List<HashMap<String,Object> list)
{
synchronized(list)
{
ArrayList newList=copy(list);
save(newList);
}
+
In Salesforce query, you can append "Limit 100;" at the end of the query to get only 100 elements in a list.
I solved the problem by using a fetch size of 100 and then used the resulting ConsumerIterator to aggregate the elements.

Creating time windows with Ruby

Having an array of several time series (timestamp, value) like this:
time_series = [[[1234567, 0.8], [1234568, 0,9], [1234569, 1.0]],
[[1234568, 0,7], [1234569, 0,2], [1234570, 1.2]],
[[1234560, 0,9], [1234561, 0.2], [1234568, 0,1]]]
I want to create an array of time windows of a given size time_size. For example, if I wanted to create time windows of time_size = 2:
time_size = 2
time_windows = create_time_windows(time_series, time_size)
puts time_windows
# time_windows => [[[], [], [[1234560, 0,9], [1234561, 0.2]]],
# [[[1234567, 0.8], [1234568, 0,9]], [[1234568, 0,7], [[1234568, 0,1]]],
# [[[1234569, 1.0]], [[1234569, 0,2], [1234570, 1.2]], []]]
I know it is not a very readable example, but the operation can be summarized as splitting an array of time series into an array of subarrays containing the segments of those time series whose timestamp is included into the pertinent interval of time.
In the example, I wanted to do that with a time window size of 2, so I picked the earliest time of the whole array of series, and began to count from there. So, my first time window contains all points from the three earlier series whose timestamp was included between 1234560 (the origin in my series, because the earlier point was that) and 1234560 + 2. You can see that the first window doesn't have elements from the first and second series, since there are no points whose timestamp was included within the interval. The next interval would be (1234560 + 2, 1234560 + 4), and so on.
I am not specially proficient in Ruby, so I would be glad if the community can help me solving this problem. I have considered using Enumerable methods such as slice_when combined with inject, but I got impossibly lost trying to code that.

Wordpress Array Conundrum

I have the following array output which I'd like to merge:
004249512651280042495126512800424951265128
There are 3 seperate arrays there, which are outputting data from a database, which has these numbers populated. These are the arrays:
00424951265128
00424951265128
00424951265128
I've tried the array_merge function to merge the data but it doesn't seem to work, I still get the same output.
The array data comprises of the following numbers:
0
0
4249
5126
5128
The code I'm using is as follows:
$player_ids = get_post_meta($post_id,"sp_player", false);
$new_player_ids = array_merge($player_ids);
foreach ( $new_player_ids as $new_player_id ){
print_r ($new_player_id);
Is there another function I've not found yet? Am I doing something wrong here. I'm not sure why one array is being repeated more than once.
Actually guys - figured it out. I had the code within a loop hence it was multiplying the array 3 times.
Fixed it woohoo!!
Thanks for looking

Should I choose a hash, an object or an array to represent a data instance in Perl?

I was always wondering about this, but never really looked thoroughly into it.
The situation is like this: I have a relatively large set of data instances. Each instance has the same set or properties, e.g:
# a child instance
name
age
height
weight
hair_color
favorite_color
list_of_hobbies
Usually I would represent a child as a hash and keep all children together in a hash of hashes (or an array of hashes).
What always bothered me with this approach is that I don't really use the fact that all children (inner hashes) have the same structure. It seems like it might be wasteful memory-wise if the data is really large, so if every inner hash is stored from scratch it seems that the names of the key names can take far more sapce than the data itself...
Also note that when I build such data structures I often nstore them to disk.
I wonder if creating a child object makes more sense in that perspective, even though I don't really need OO. Will it be more compact? Will it be faster to query?
Or perhaps representing each child as an array makes sense? e.g.:
my ($name, $age, $height, $weight, $hair_color, $favorite_color, $list_of_hobbies) = 0..7;
my $children_h = {
James => ["James", 12, 1.62, 73, "dark brown", "blue", ["playing football", "eating ice-cream"]],
Norah => [...],
Billy => [...]
};
print "James height is $children_h->{James}[$height]\n";
Recall my main concerns are space efficiency (RAM or disk when stored), time efficiency (i.e. loading a stored data-set then getting the value of property x from instance y) and ... convenience (code readability etc.).
Thanks!
Perl is smart enough to share keys among hashes. If you have 100,000 hashes with the same five keys, perl stores those five strings once, and references to them a hundred thousand times. Worrying about the space efficiency is not worth your time.
Hash-based objects are the most common kind and the easiest to work with, so you should use them unless you have a damn good reason not to.
You should save yourself a lot of trouble, start using Moose, and stop worrying about the internals of your objects (although, just between you and me, Moose objects are hash-based unless you use special extensions to make them otherwise -- and once again, you shouldn't do that without a really good reason.)
I guess it is mainly personal taste (except of course when other people have to work on your code too)
Anyway, I think you should look into moose It is definitely not the most time nor space efficient, but it is the most pleasant and most secure way of working.
(By secure, I mean that other people that use your object can't misuse it as easily)
I personally prefer an object when I'm really representing something.
And when I work with objects in perl, I prefer moose
Gr,
ldx
Unless absolute speed tuning is a requirement, I would make an object using Moose. For pure speed, use constant indexes and an array.
I like objects because they reduce the mental effort needed to work with big deep structures. For example, if you build a data structure to represent the various classrooms in a school. You'll have something like a list of kids, a teacher and a room number. If you have everything in a big structure you have to know the structure internals access the hobbies of the children in the classroom. With objects, you can do somthing like:
my #all_hobbies = uniq map $_->all_hobbies,
map $_->all_students, $school->all_classrooms;
I don't care about the internals. And I can concisely generate a unique list of all the kids hobbies. All the complicated accesses are still happening, but I don't need to worry about what is happening. I can simply use the interface.
Here's a Moose version of your child class. I set up the hobbies attribute to use the array trait, so we get a bunch of methods simply for the asking.
package Child;
use Moose;
has [ 'name', 'hair_color', 'fav_color' ] => (
is => 'ro',
isa => 'Str',
required => 1,
);
has [ 'age', 'height', 'weight' ] => (
is => 'ro',
isa => 'Num',
required => 1,
);
has hobbies => (
is => 'ro',
isa => 'Int',
default => sub {[]},
traits => ['Array'],
handles => {
has_no_hobbies => 'is_empty',
num_hobbies => 'count',
has_hobbies => 'count',
add_hobby => 'push',
clear_hobbies => 'clear',
all_hobbies => 'elements',
},
);
# Good to do these, see moose best practices manual.
__PACKAGE__->meta->make_immutable;
no Moose;
Now to use the Child class:
use List::MoreUtils qw( zip );
# Bit of messing about to make array based child data into objects;
#attributes = qw( name age height weight hair_color fav_color hobbies );
my #children = map Child->new( %$_ ),
map { zip #attributes, #$_ },
["James", 12, 1.62, 73, "dark brown", "blue", ["playing football", "eating ice-cream"]],
["Norah", 13, 1.75, 81, "black", "red", ["computer programming"]],
["Billy", 11, 1.31, 63, "red", "green", ["reading", "drawing"]],
;
# Now index by name:
my %children_by_name = map { $_->name, $_ } #children;
# Here we get kids with hobbies and print them.
for my $c ( grep $_->has_hobbies, #children ) {
my $n = $c->name;
my $h = join ", ", $c->all_hobbies;
print "$n likes $h\n";
}
I usually start with a hash and manipulate that, until I find instances where the data I really want is derived from the data that I have. And/or that I want some sort of peculiar--or even polymorphic--behavior.
At that point, I start creating a packages to store class behavior, implementing methods as needed.
Another case is where I think this data would be useful in more than one instance. In that case, it's either rewrite all the selection cases everywhere where you think you'll need it or package the behavior in a class, so that you don't have to do too much copying or studying of the cases the next time you want to use that data.
Generally, if you don't need utter efficiency, hashes will be your best bet. In Perl an object is just a $something with a class name attached. The object can be a hash, an array, a scalar, a code reference, or even a glob reference inside. So objects can only possibly be a win in convenience, not efficiency.
If you want to give an array a shot, the typical way of making that somewhat maintainable is using constants for the field names:
use strict;
use warnings;
use constant {
NAME => 0,
AGE => 1,
HEIGHT => 2,
WEIGHT => 3,
HAIR_COLOR => 4,
FAVORITE_COLOR => 5,
LIST_OF_HOBBIES => 6,
};
my $struct = ["James", 12, 1.62, 73, "dark brown", "blue", ["playing football", "eating ice-cream"]];
# And then access it with the constants as index:
print $struct->[NAME], "\n";
$struct->[AGE]++; # happy birthday!
Alternatively, you could try whether using an array (object) as follows makes more sense:
package MyStruct;
use strict;
use warnings;
use Class::XSAccessor::Array
accessors => {
name => 0,
age => 1,
height => 2,
weight => 3,
hair_color => 4,
favorite_color => 5,
list_of_hobbies => 6,
};
sub new {
my $class = shift;
return bless([#_] => $class);
}
package main;
my $s = MyStruct->new;
$s->name("James");
$s->age(12);
$s->height(1.62);
$s->weight(73);
# ... you get the drill, but take care: The following is fine:
$s->list_of_hobbies(["foo", "bar"]);
# This can produce action-at-a-distance:
my $hobbies = ["foo", "bar"];
$s->list_of_hobbies($hobbies);
$hobbies->[1] = "baz"; # $s changed, too (due to reference)
Coming back to my original point: Usually, you want hashes or hash-based objects.
Whenever I try to decide between using a hash or an array to store data, I almost always use a hash. I can almost always find a useful way to index the values in the list for quick lookup. However, your question is more about hashes of array refs vs hashes of hash refs vs hashes of object refs.
In your example above, I would have used a hash of hash refs rather than a hash of array refs. The only time I would use an array is when there is an inherent order in the data that should be maintained, that way I can look things up in order. In this case, there isn't really any inherent order in the arrays you're storing (e.g., you arbitrarily chose height before weight), so it would be more appropriate (in my humble opinion) to store the data as a hash where the keys are descriptions of the data you're storing (name, height, weight, etc).
As to whether you should use a hash of hash refs or a hash of object refs, that can often be a matter of preference. There is some overhead associated with object-oriented Perl, so I try only to use it when I can get a large benefit in, say, usability. I usually only use objects/classes when there are actions inherently associated with the data (so I can write $my_obj->fix(); rather than fix($my_obj);). If you're just storing data, I would say stick with a hash.
There should not be a significant difference in RAM usage or in time to read from/write to disk. In terms of readability, I think you will get a huge benefit using hashes over arrays, since with the hashes the keys actually make sense, but the arrays are just indexed by numbers that have no real relationship with the data. This may require more disk space for storage if you're storing in plain text, but if that's a huge concern you can always compress the data!

Resources