how to order array evenly by property - ruby

I have the following array:
arr = [
{ name: 'Apple', store: 'A' },
{ name: 'Banana', store: 'A' },
{ name: 'Carrot', store: 'B' },
{ name: 'Potato', store: 'B' },
{ name: 'Tomato', store: 'A' }
]
I need to sort the array by switching between each store like this:
arr = [
{ name: 'Apple', store: 'A' },
{ name: 'Carrot', store: 'B' },
{ name: 'Banana', store: 'A' },
{ name: 'Tomato', store: 'B' },
{ name: 'Potato', store: 'A' }
]
How can I do that with ruby ?

I came up with something :)
arr = [
{ name: 'Apple', store: 'A' },
{ name: 'Banana', store: 'A' },
{ name: 'Carrot', store: 'B' },
{ name: 'Potato', store: 'B' },
{ name: 'Tomato', store: 'A' }
]
first, *rest = arr.group_by { |h| h[:store] }.values
first.zip(*rest).flatten.compact
See it in action: Replit

Related

D3.js Traverse Through Nested Array to Find Max Value

I have a nested array that looks like this:
Nested Array
I would like to traverse through the nested array and find the max value of the 'value' field situated in grouped_ratings > values > value
I have tried the following and can't seem to figure out the issue.
var yMax = d3.max(grouped_ratings, function(g) {
return d3.map(g.values, function(v) {
return d3.max(v.value)
})
});
Change d3.map to d3.max and in the inner-most function, you can just return v.value. Here's what it looks like:
d3.max(grouped_ratings, function (g) {
return d3.max(g.values, function (v) {
return v.value;
});
});
Or as a one-liner: d3.max(grouped_ratings, g => d3.max(g.values, v => v.value))
These snippets work when grouped_ratings has the format
grouped_ratings = [
{
key: '2011',
values: [
{ key: '1', value: 151 },
{ key: '2', value: 12 },
{ key: '3', value: 314 },
{ key: '4', value: 178 },
{ key: '5', value: 31 },
{ key: '6', value: 1 },
{ key: '7', value: 1 },
]
},
{
key: '2012',
values: [
{ key: '1', value: 203 },
{ key: '2', value: 4 },
{ key: '3', value: 41 },
{ key: '4', value: 87 },
{ key: '5', value: 13 },
{ key: '6', value: 10 },
{ key: '7', value: 100 },
]
},
]

Using nested datatable in laravel and build my own json

I am using Nested-datatables (https://github.com/AndrejGajdos/nested-datatables) so I have to use JSON.
I want to pass JSON from the controller to ajax and then use it in order to create a nested table.
The problem is that I need the exact JSON format so I will not get "undefined" result.
This is the example of the JSON format that I need (like in the link above) :
var dataInJson = [
{
data: {
name: 'b1',
street: 's1',
city: 'c1',
departments: 10,
offices: 15
},
kids: [
{
data: {
department: 'HR',
supervisor: 'Isidor Bristol',
floor: 1,
employees: 15
},
kids: [
{
data: {
name: 'Klement Nikodemos',
phone: '+938462',
hire_date: 'January 1, 2010',
id: 3456
},
kids: []
},
{
data: {
name: 'Madhava Helmuth',
phone: '+348902',
hire_date: 'May 23, 2002',
id: 1234
},
kids: []
},
{
data: {
name: 'Andria Jesse',
phone: '456123',
hire_date: 'October 23, 2011',
id: 9821
},
kids: []
}
]
},
{
data: {
department: 'development',
supervisor: 'Jim Linwood',
floor: 2,
employees: 18
},
kids: [
{
data: {
name: 'Origenes Maxwell',
phone: '345892',
hire_date: 'February 1, 2004',
id: 6234
},
kids: []
}
]
},
{
data: {
department: 'testing',
supervisor: 'Zekeriya Seok',
floor: 4,
employees: 11
},
kids: []
}
]
},
{
data: {
name: 'b2',
street: 's10',
city: 'c2',
departments: 3,
offices: 10
},
kids: [
{
data: {
department: 'development',
supervisor: 'Gallagher Howie',
floor: 8,
employees: 24
},
kids: [
{
data: {
name: 'Wat Dakota'
},
kids: []
}
]
},
{
data: {
department: 'testing',
supervisor: 'Shirley Gayle',
floor: 4,
employees: 11
},
kids: []
}
]
},
{
data: {
name: 'b3',
street: 's3',
city: 'c3',
departments: 2,
offices: 1
},
kids: [
{
data: {
department: 'development'
},
kids: [
{
data: {
name: 'Wat Dakota'
},
kids: []
}
]
},
{}
]
},
{
data: {
name: 'b4',
city: 'c4'
},
kids: []
}
];
In controller I have ajax function:
public function ajax(){
$parent = FirstLine::
select('yehida','data_type')
->where('first_year',2019)->where('second_year',2019)->where('first_period_no',1)->where('second_period_no',2)->where('periodical','רבעוני')
->addSelect(DB::raw('SUM(first_period) as first_period'))
->groupBy('yehida')
->groupBy('data_type')
->orderBy('yehida')
->orderBy('data_type')
->get();
$child = FirstLine::
select('yehida','hativa','data_type')
->where('first_year',2019)->where('second_year',2019)->where('first_period_no',1)->where('second_period_no',2)->where('periodical','רבעוני')
->addSelect(DB::raw('SUM(first_period) as first_period'))
->groupBy('yehida')
->groupBy('hativa')
->groupBy('data_type')
->orderBy('yehida')
->orderBy('hativa')
->orderBy('data_type')
->get();
$value = [];
foreach ($parent as $ch) {
$options = [];
foreach($child as $ch2) {
$options[] = ['data' => [
'yehida' => $ch2->yehida,
'hativa' => $ch2->hativa,
'data_type' => $ch2->data_type,
'first_period' => $ch2->first_period],
'kids' => []
];
if($ch->yehida == $ch2->yehida){
$value[] = [
'data' =>[
'yehida' => $ch->yehida,
'data_type' => $ch->data_type,
'first_period' => $ch->first_period
],
'kids' =>
$options,
];
}
}
}
$value = json_encode($value);
return response()->json($value);
}
My script with ajax call:
<script>
var temp;
$.ajax({
'async': false,
type: 'GET', //THIS NEEDS TO BE GET
url: '{!! route('get.ajax') !!}',
dataType: 'json',
success: function (data) {
temp = data;
},error:function(){
console.log(data);
}
});
var dataInJson = temp;
var settings = {
iDisplayLength: 20,
bLengthChange: false,
bFilter: false,
bSort: false,
bInfo: false
};
var tableT = new nestedTables.TableHierarchy(
'example',
dataInJson,
settings
);
tableT.initializeTableHierarchy();
var tableEle = document.querySelector('#example .table');
tableEle.addEventListener('onShowChildHierarchy', function(e) {
console.log(e);
});
// '#example' is wrapper ID for table hierarchy
var tableEle = document.querySelector('#example .table');
tableEle.addEventListener('onHideChildHierarchy', function(e) {
console.log(e);
});
</script>
How am I supposed to build my own JSON format so it will be like the JSON example? please help me

How to merge array of hashes based on hash value but not merge values instead override

I have an array of hashes like this:
[
{ name: 'Pratha', email: 'c#f.com' },
{ name: 'John', email: 'j#g.com' },
{ name: 'Clark', email: 'x#z.com' },
]
And this is second group array of hashes:
[
{ name: 'AnotherNameSameEmail', email: 'c#f.com' },
{ name: 'JohnAnotherName', email: 'j#g.com' },
{ name: 'Mark', email: 'd#o.com' },
]
What I want is, merge these two arrays into one, merge based on :email and keep latest (or first) :name.
Expected Result (latest name overrided):
[
{ name: 'AnotherNameSameEmail', email: 'c#f.com' },
{ name: 'JohnAnotherName', email: 'j#g.com' },
{ name: 'Mark', email: 'd#o.com' },
{ name: 'Clark', email: 'x#z.com' },
]
or (first name preserved)
[
{ name: 'Pratha', email: 'c#f.com' },
{ name: 'John', email: 'j#g.com' },
{ name: 'Mark', email: 'd#o.com' },
{ name: 'Clark', email: 'x#z.com' },
]
So, basically, I want to group by :email, retain one :name, drop dupe emails.
The examples found on SO is creates an array of values for :name.
Ruby 2.6.3
Maybe you could just call Array#uniq with a block on email key of the concatenation (Array#+) of the two arrays:
(ary1 + ary2).uniq { |h| h[:email] }
a1 = [
{ name: 'Pratha', email: 'c#f.com' },
{ name: 'John', email: 'j#g.com' },
{ name: 'Clark', email: 'x#z.com' },
]
a2 = [
{ name: 'AnotherNameSameEmail', email: 'c#f.com' },
{ name: 'JohnAnotherName', email: 'j#g.com' },
{ name: 'Mark', email: 'd#o.com' },
]
Let's first keep the last:
(a1+a2).each_with_object({}) { |g,h| h.update(g[:email]=>g) }.values
#=> [{:name=>"AnotherNameSameEmail", :email=>"c#f.com"},
# {:name=>"JohnAnotherName", :email=>"j#g.com"},
# {:name=>"Clark", :email=>"x#z.com"},
# {:name=>"Mark", :email=>"d#o.com"}]
To keep the first, do the same with (a1+a2) replaced with (a2+a1), to obtain:
#=> [{:name=>"Pratha", :email=>"c#f.com"},
# {:name=>"John", :email=>"j#g.com"},
# {:name=>"Mark", :email=>"d#o.com"},
# {:name=>"Clark", :email=>"x#z.com"}]

Normalizing a nested entity that shares the current schema

My goal is to normalize this object:
{
talks: [
{
id: 1755,
speakers: [
{
id: 1487,
name: 'John Doe',
},
],
related_talks: [{
id: 14,
speakers: [{
id: 125,
name: 'Jane Doe',
}],
event: {
id: 181,
name: 'First Annual',
},
}],
event: {
id: 180,
name: 'July Party',
},
},
],
};
into this result:
{
entities: {
events: {
181: {
id: 181,
name: 'First Annual'
},
180: {
id: 180,
name: 'July Party'
}
},
speakers: {
125: {
id: 125,
name: 'Jane Doe'
},
1487: {
id: 1487,
name: 'John Doe'
}
},
talks: {
1755: {
id: 1755,
event: 181,
speakers: [ 1487 ],
related_talks: [ 14 ],
},
14: {
id: 14,
speakers: [ 125 ],
event: 180,
}
},
},
result: {
talks: [ 1755, 14 ],
},
}
If you'll notice, the items in related_talks are treated the same as a talk.
My schemas follow the examples and are set up like this:
const speaker = new schema.Entity('speakers');
const event = new schema.Entity('events');
export const talk = new schema.Entity('talks', {
speakers: [speaker],
event,
});
talk.define({ related_talks: [talk] });
No matter what I try, I can't get the items in related_talks to be added to the result.talks array. It is, however, in the entities object.
What is my schema configuration missing in order to accommodate this?
Unfortunately, if this is your requirement, Normalizr is not for you. Alternatively, if you're looking for a list of "talks" by ID, you can use Object.keys(data.entities.talks)

Convert and modify ruby hash to new hash

How could I convert my hash to 2 very different hashes?
My hash:
{ "grey"=> ["421_01.jpg", "421_02.jpg", "421_03.jpg"],
"heather blue"=> ["422_01.jpg", "422_02.jpg", "422_03.jpg"],
"indigo"=> [],
"dark grey"=> ["435_01.jpg", "435_02.jpg", "435_03.jpg"] }
1. Desired hash: (all values from my hash)
[{ src: "421_01.jpg" },
{ src: "421_02.jpg" },
{ src: "421_03.jpg" },
{ src: "422_01.jpg" },
{ src: "422_02.jpg" },
{ src: "422_03.jpg" },
{ src: "435_01.jpg" },
{ src: "435_02.jpg" },
{ src: "435_03.jpg" }]
2. Desired hash:
[{
image: "421_01.jpg, 421_02.jpg, 421_03.jpg",
attributes: [
{
name: "Color",
option: "grey"
}
]
},
{
image: "422_01.jpg, 422_02.jpg, 422_03.jpg",
attributes: [
{
name: "Color",
option: "heather blue"
}
]
},
{
image: "",
attributes: [
{
name: "Color",
option: "indigo"
}
]
},
{
image: "435_01.jpg, 435_02.jpg, 435_03.jpg",
attributes: [
{
name: "Color",
option: "dark grey"
}
]
}]
Please note: empty array in my hash shouldn't add any images to color variation, but should add variation with empty image string. (All shown in examples)
h = { "grey"=> ["421_01.jpg", "421_02.jpg", "421_03.jpg"],
"heather blue"=> ["422_01.jpg", "422_02.jpg", "422_03.jpg"],
"indigo"=> [],
"dark grey"=> ["435_01.jpg", "435_02.jpg", "435_03.jpg"] }
a = h.values
#=> [["421_01.jpg", "421_02.jpg", "421_03.jpg"],
# ["422_01.jpg", "422_02.jpg", "422_03.jpg"],
# [],
# ["435_01.jpg", "435_02.jpg", "435_03.jpg"]]
For #1:
a.flat_map { |s| { src: s } }
#=> [{:src=>"421_01.jpg"}, {:src=>"421_02.jpg"}, {:src=>"421_03.jpg"},
# {:src=>"422_01.jpg"}, {:src=>"422_02.jpg"}, {:src=>"422_03.jpg"},
# {:src=>"435_01.jpg"}, {:src=>"435_02.jpg"}, {:src=>"435_03.jpg"}]
For #2:
h.map { |k,_| { image: a.shift.join(', '),
attributes: [{ name: "Color", option: k }] } }
# => [{:image=>"421_01.jpg, 421_02.jpg, 421_03.jpg",
:attributes=>[{:name=>"Color", :option=>"grey"}]},
{:image=>"422_01.jpg, 422_02.jpg, 422_03.jpg",
:attributes=>[{:name=>"Color", :option=>"heather blue"}]},
{:image=>"", :attributes=>[{:name=>"Color", :option=>"indigo"}]},
{:image=>"435_01.jpg, 435_02.jpg, 435_03.jpg",
:attributes=>[{:name=>"Color", :option=>"dark grey"}]}]

Resources