I have two hashes of hashes that look basically like:
sales = {
"2013-03-15": {sales: 5},
"2013-03-14": {sales: 3},
"2013-03-12": {sales: 8},
... }
and
views = {
"2013-03-15": {views: 30},
"2013-03-14": {views: 23},
"2013-03-13": {views: 35},
... }
How can I merge them into a single hash that looks like:
data = {
"2013-03-15": {views: 30, sales: 5},
"2013-03-14": {views: 23, sales: 3},
"2013-03-13": {views: 35, sales: 0}, # or just {views: 35}
... }
Basically, I need to keep the keys and all the data intact.
data = views.merge sales Seems to override all the views data, leaving me with basically just the sales hash.
Edit: I can also convert the sales or views hashes into simple hashes (not hashes of hashes), but I still don't know a good way to proceed.
This:
sales.merge(views) { |k, o, n| o.merge(n) }
Runnable example:
views = {
"2013-03-15" => {:views=> 30},
"2013-03-14" => {:views=> 23},
"2013-03-13" => {:views=> 35},
}
sales = {
"2013-03-15" => {:sales=> 5},
"2013-03-14" => {:sales=> 3},
"2013-03-12" => {:sales=> 8},
}
puts sales.merge(views) { |k, o, n| o.merge(n) }
=> {"2013-03-15"=>{:sales=>5, :views=>30}, "2013-03-14"=>{:sales=>3, :views=>23}, "2013-03-12"=>{:sales=>8}, "2013-03-13"=>{:views=>35}}
Related
trying to figure out dc.js scatter plot and getting hung up on structuring the inital data for it I think
var data = [
{ category: 'A', processVersion: 6},
{ category: 'A', processVersion: 6},
{ category: 'A', processVersion: 8},
{ category: 'A', processVersion: 7},
{ category: 'A', processVersion: 6},
{ category: 'A', processVersion: 7},
{ category: 'A', processVersion: 6},
{ category: 'A', processVersion: 7},
{ category: 'B', processVersion: 6},
{ category: 'B', processVersion: 8},
{ category: 'B', processVersion: 8},
{ category: 'B', processVersion: 7},
{ category: 'B', processVersion: 8}
];
var cf = crossfilter(data);
var dim = cf.dimension(function(d){ return [d.category, d.processVersion]; });
var grp = dim.group();
var scatterChart = dc.scatterPlot("#scatter-chart");
scatterChart
.width(500)
.height(300)
.margins({
top: 10,
right: 20,
bottom: 30,
left: 40
})
.dimension(dim)
.group(grp)
.x(d3.scale.linear().domain[0, 10]) // for each process version
.y(d3.scale.linear().domain[0, 10]) // want count of records where categorys are like
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true)
.symbolSize(30)
.highlightedSize(8)
scatterchart.render();
What I want is to have the y as a count of each record that shares a given category per a given service version(x axis). So I have tried getting a count function into the initial dimesion array, or processing the data before hand which seems unnecessary because I am guessing there is a proper way to do that in crossfilter? the group result should have a key = [5, 3, "A"] I think where [0] is the processVersion, [1] is the count, etc.
Appreciate the assistance.
I observed that while providing duplicate ticklabels (with an aim to mention the class of categorical variable), plotly creates a unique set and displays only the non-repeated tick labels. Is there a way to by-pass this feature and allow duplicate tick-labels?
var data = [
{
z: [[1, 20, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20]],
x: ['Healthy', 'Healthy', 'Moderate', 'Diseased', 'Diseased'],
y: ['Morning', 'Afternoon', 'Evening'],
type: 'heatmap'
}
];
Plotly.newPlot('myDiv', data);
Following is the jsfiddle depicting the issue:
https://jsfiddle.net/mam8sgwx/
Set the layout with ticktext:
var layout = {
xaxis: {
tickmode: "array",
ticktext: ['Healthy', 'Healthy', 'Moderate', 'Diseased', 'Diseased'],
tickvals: [0, 1, 2, 3, 4]
}
}
Here is the demo:
var data = [{
z: [
[1, 20, 30, 50, 1],
[20, 1, 60, 80, 30],
[30, 60, 1, -10, 20]
],
y: ['Morning', 'Afternoon', 'Evening'],
type: 'heatmap'
}];
var layout = {
xaxis: {
tickmode: "array",
ticktext: ['Healthy', 'Healthy', 'Moderate', 'Diseased', 'Diseased'],
tickvals: [0, 1, 2, 3, 4]
}
}
Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<body>
<div id="myDiv"></div>
I have objects that have a following structure:
[
{
'record': 1,
'tags': [1, 2],
'data': {
'1': 10,
'2': 15
}
},
...
{
'record': 1,
'tags': [3, 4, 5],
'data': {
'1': 100,
'2': 150
}
}
]
How can I get distinct lists of data: [10, ..., 100] and [15, ..., 150] to process each of them?
Thanks
If all data have same key, I proposed this map-reduce process.
.map(function(doc) {
return doc('data').keys().map(function(key) {
return [key, [doc('data')(key)]]
}).coerceTo('object')
})
.reduce(function(left, right) {
return left.keys().map(function(key) {
return [key, left(key).setUnion(right(key))]
})
.coerceTo('object')
})
With your data set, we have:
r.expr(
[
{
'record': 1,
'tags': [1, 2],
'data': {
'1': 10,
'2': 15
}
},
{
'record': 1,
'tags': [1, 2],
'data': {
'1': 19,
'2': 100
}
},
{
'record': 1,
'tags': [3, 4, 5],
'data': {
'1': 100,
'2': 150
}
}
]
)
.map(function(doc) {
return doc('data').keys().map(function(key) {
return [key, [doc('data')(key)]]
}).coerceTo('object')
})
.reduce(function(left, right) {
return left.keys().map(function(key) {
return [key, left(key).setUnion(right(key))]
})
.coerceTo('object')
})
Which produces:
{
"1": [10, 19, 100],
"2": [15, 100, 150]
}
You can call values on an object to get an array of values from it: https://www.rethinkdb.com/api/javascript/#values
If not all of the indexes are present as keys, you could write something like r.range(obj.keys().max()).map(function(i) { return obj(i.coerceTo('string')).default(nil); }).
If the data fields could be any string, something like this could work:
r.db('test')
.table('test')
.getAll(1, {index: 'record'})
.getField('data')
.concatMap(r.row.coerceTo('array'))
.group(r.row(0))
.concatMap([r.row(1)])
.ungroup()
Otherwise, mlucy's suggestion might be used to make it more efficient.
EDIT: on further experimentation, I could not get obj.keys() to be faster than group.
In 2D I write:
Dim matr2D(,) As Integer = { {10, 20, 30}, {11, 21, 31}, {12, 22, 32} }.
In 3D?
Found:
Dim matr3D(, ,) As Integer = { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } }
https://msdn.microsoft.com/it-it/library/2yd9wwz4.aspx
I have a list the following hashes:
{
key_main1: {
k1: 1,
k2: 11,
k3: 33,
k4: 146,
k5: 12,
# etc
},
key_main2: {
k1: 1,
k2: 11,
k3: 33,
k4: 146,
k5: 12,
# etc
},
# etc
}
which is save in a redis as json:
redis_key1 = "redis_key1"
redis.set("redis_key", my_hash.to_json)
redis.get("redis_key") # =>
"{"key_main":{"k1":1,"k2":11,"k3":33,"k4":146,"k5":12}}"
The hashes have the same structure but can have different keys. On each iteration I want to update the existing keys by summing up the values of "k"s or/and insert the keys that don't exist:
So the second hash in the list looks like this
{
key_main1: {
k3: 44,
k4: 14,
k18: 99
},
key_main3: {
k2: 77
}
}
Then after the seconds iteration the result in Redis will look like the following:
{
key_main1: {
k1: 1,
k2: 11,
k3: 33,
k4: 160,
k5: 12,
k18: 99
},
key_main2: {
k1: 1,
k2: 11,
k3: 33,
k4: 146,
k5: 12
},
key_main3: {
k2: 77
}
}
What's the easiest and best way to do it? Do I have to parse (restore)json in each iteration in order to check if the keys exist and update or insert them?
The best way is to parse the JSON back into a hash, otherwise you will have a really hard time figuring out how to combine the hashes.
To combine them, the best and easiest is with Hash#merge:
h1 = { m1: { k1: 10, k2: 20, k3: 30 }, m2: { k1: 11, k2: 12 } }
h2 = { m1: { k1: 500, k2: 5, k4: 40 }, m3: { k2: 123 } }
pp h1.merge(h2) { |key, v1, v2|
v1.merge(v2) { |key, v1, v2| v1 + v2 }
}
=> { :m1 => { :k1 => 510,:k2 => 25, :k3 => 30, :k4 => 40 },
:m2 => { :k1 => 11, :k2 => 12},
:m3 => { :k2 => 123 } }
This code assumes the keys in h1 and h2 always contain a hash with integer keys.