I have a couple time_tables in this array. There are four time_tables that are related to each other in a linear way by their start_location - end_location and start_date - end_date.
When the first time_table ends, the other time_table starts, and so on.
My code:
arr = [
{ name: 01, start_date: '2014-04-24 22:03:00', start_location: 'A', end_date: '2014-04-24 22:10:00', end_location: 'B' },
{ name: 05, start_date: '2014-04-24 22:10:00', start_location: 'C', end_date: '2014-04-24 23:10:00', end_location: 'D' },
{ name: 01, start_date: '2014-04-24 17:10:00', start_location: 'X', end_date: '2014-04-24 20:10:00', end_location: 'B' },
{ name: 01, start_date: '2014-04-24 17:10:00', start_location: 'Z', end_date: '2014-04-24 20:10:00', end_location: 'B' },
{ name: 06, start_date: '2014-04-24 20:15:00', start_location: 'B', end_date: '2014-04-24 22:10:00', end_location: 'C' },
{ name: 03, start_date: '2014-04-24 23:15:00', start_location: 'D', end_date: '2014-04-24 00:10:00', end_location: 'E' }
]
new_array = []
i = 0
while i <= 5 do
if arr[i][:end_location] == arr[i+1][:start_location] && arr[i][:start_date] <= arr[i+1][:start_date]
new_array << arr[i+1]
end
i = i + 1
end
This is the result that I want:
# My expexpected result will be this:
# [
# { name: 01, start_date: '2014-04-24 22:03:00', start_location: 'A', end_date: '2014-04-24 22:10:00', end_location: 'B' },
# { name: 06, start_date: '2014-04-24 22:15:00', start_location: 'B', end_date: '2014-04-24 22:20:00', end_location: 'C' },
# { name: 05, start_date: '2014-04-24 22:20:00', start_location: 'C', end_date: '2014-04-24 23:10:00', end_location: 'D' },
# { name: 03, start_date: '2014-04-24 23:15:00', start_location: 'D', end_date: '2014-04-24 00:10:00', end_location: 'E' }
#
]
but my algorithm is seems to be bad. Thank you for insights to make this work.
Aren't you really looking for the longest linear sub sequent time tables ? I wanted to clarify that through comments but I didn't have the permission to comment. Also there is a difference between the value of start_date of B (and start_location B) in input and the output, so I'm assuming it's a mistake.
I have written the solution considering you want to find the longest linear sub sequent time tables.
require 'date'
def getLLTT(time_tables)
longest = []
time_tables.sort_by! do |time_table|
DateTime.parse(time_table[:start_date]).to_time
end
0.upto(time_tables.size-1) do |i|
long_for_i = [time_tables[i]]
0.upto(i-1) do |j|
j_end_date = DateTime.parse(longest[j][-1][:end_date]).to_time
i_start_date = DateTime.parse(time_tables[i][:start_date]).to_time
if j_end_date <= i_start_date
if longest[j][-1][:end_location].eql? time_tables[i][:start_location]
if longest[j].size + 1 > long_for_i.size
long_for_i = longest[j] + [time_tables[i]]
end
end
end
end
longest[i] = long_for_i
end
return longest[-1]
end
puts getLLTT(arr)
So given the input :
arr = [
{ name: 01, start_date: '2014-04-24 22:03:00', start_location: 'A', end_date: '2014-04-24 22:10:00', end_location: 'B' },
{ name: 05, start_date: '2014-04-24 22:10:00', start_location: 'C', end_date: '2014-04-24 23:10:00', end_location: 'D' },
{ name: 01, start_date: '2014-04-24 17:10:00', start_location: 'X', end_date: '2014-04-24 20:10:00', end_location: 'B' },
{ name: 01, start_date: '2014-04-24 17:10:00', start_location: 'Z', end_date: '2014-04-24 20:10:00', end_location: 'B' },
{ name: 06, start_date: '2014-04-24 20:15:00', start_location: 'B', end_date: '2014-04-24 22:10:00', end_location: 'C' },
{ name: 03, start_date: '2014-04-24 23:15:00', start_location: 'D', end_date: '2014-04-24 00:10:00', end_location: 'E' }
]
The output will be :
[
{:name=>1, :start_date=>"2014-04-24 17:10:00", :start_location=>"Z", :end_date=>"2014-04-24 20:10:00", :end_location=>"B"}
{:name=>6, :start_date=>"2014-04-24 20:15:00", :start_location=>"B", :end_date=>"2014-04-24 22:10:00", :end_location=>"C"}
{:name=>5, :start_date=>"2014-04-24 22:10:00", :start_location=>"C", :end_date=>"2014-04-24 23:10:00", :end_location=>"D"}
{:name=>3, :start_date=>"2014-04-24 23:15:00", :start_location=>"D", :end_date=>"2014-04-24 00:10:00", :end_location=>"E"}
]
This will "join" your time series by consecutive end and start location.
def span x; x[:end_location].ord - x[:start_location].ord; end
def diff x, y; x[:start_location].ord - y[:start_location].ord; end
arr = arr.sort_by { |x| [x[:start_location], span(x)] }
prev = arr[0]
arr = arr.slice_before { |e|
prev, prev2 = e, prev
diff(prev, prev2) != 0
}.to_a.map(&:first).chunk(&method(:span)).first[1]
For example, I get
arr.map { |x| [x[:start_location], x[:end_location] }
=> [["A", "B"], ["B", "C"], ["C", "D"], ["D", "E"]]
Related
If I have an array of items like
[
{id: 1, name: 'Sam', gender: 'boy'},
{id: 2, name: 'Mary', gender: 'girl'},
{id: 3, name: 'Sam', gender: 'boy'}
]
Matching on just name and gender, how do I reduce it to the following result?
[
{id: 1, name: 'Sam', type: 'boy'},
{id: 2, name: 'Mary', type: 'girl'}
]
Let try
items$.pipe(map(this.uniqueArray))
uniqueArray(array: any[]): any[] {
return array.filter(
(item, index, self) =>
index === self.findIndex((x) => x.name === item.name)
);
}
https://stackblitz.com/edit/angular-isqjpa?file=src/app/hello.component.ts
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
How can I filter the current data:
[{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02 18:20:00.000+0200'}],
fare: { type: 'B', price: 25 }
},{
key: 'T1',
legs:[{ fno: 'W321', date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 23 }
},{
key: 'T1',
legs:[{ fno: 'W321', date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 20}
}]
I want to group by legs[0].fno, legs[0].date and fare.type, and keep the lowest priced items in each group. This is the expected result:
[{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'B', price: 25}
},{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 20}
}]
Use _.groupBy() with a callback to create a string to group by, then _.map() each group to a single item using _.minBy():
var data = [{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02 18:20:00.000+0200"}],"fare":{"type":"B","price":25}},{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02T18:20:00.000+0200"}],"fare":{"type":"E","price":23}},{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02T18:20:00.000+0200"}],"fare":{"type":"E","price":20}}];
var result = _(data)
// group by the combined group keys
.groupBy(function(o) {
// extract all group keys and join them to a string
return _.at(o, ['key', 'legs[0].date', 'fare.type']).join('');
})
.map(function(group) {
// get the object object with the minimum fare.price
return _.minBy(group, 'fare.price');
})
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
I've got an array full of hashes of which I want to combine specific keys to a new one, e.g.
[{ firstname: 'john', lastname: 'doe', something: 'else', key: ... }, { firstname: 'Joe', lastname: 'something', something: 'bla', key:... }]
should become
[{ name: 'john doe' },{ name: 'Joe something' }]
Please note: there are more keys in the hash as first and lastname. Is there a common ruby method to do this? Thanks!
Just do as
array = [{ firstname: 'john', lastname: 'doe' }, { firstname: 'Joe', lastname: 'something' }]
array.map { |h| { :name => h.values_at(:firstname, :lastname) * " " } }
# => [{:name=>"john doe"}, {:name=>"Joe something"}]
Read this Hash#values_at and Array#* .
This is:
a = [{ firstname: 'john', lastname: 'doe' }, { firstname: 'Joe', lastname: 'something' }]
a.map { |n| { name: n.values.join(' ') } }
# => [{:name=>"john doe"}, {:name=>"Joe something"}]
I have multiple (6) editables with two different classes (.html_edit_simple, .html_edit_advanced) on website and I want to divide them by class and each to have its own contentHandler settings.
But no matter what I try, only the default settings are loaded.
The ones defined under window.Aloha.settings.contentHandler.handler.sanitize don't apply at all.
The settings code that I use is the following:
(function(window, undefined) {
if (window.Aloha === undefined || window.Aloha === null) {
window.Aloha = {};
}
window.Aloha.settings = { sidebar: { disabled: true } };
window.Aloha.settings.contentHandler = {
insertHtml: [ 'word', 'generic', 'oembed', 'sanitize' ],
initEditable: [ 'sanitize' ],
getContents: [ 'blockelement', 'sanitize', 'basic' ],
sanitize: 'relaxed', // relaxed, restricted, basic,
allows: {
elements: ['strong', 'em', 'i', 'b', 'blockquote', 'br', 'cite', 'code', 'dd', 'div', 'dl', 'dt', 'em', 'i', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike', 'sub', 'sup', 'u', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'img', 'video', 'audio']
},
handler: {
generic: {
transformFormattings: false
},
sanitize: {
'.html_edit_simple': { elements: [ 'b', 'i', 'strong', 'em', 'strike', 'u', 'a' ] },
'.html_edit_advanced': { elements: [ 'b', 'i', 'strong', 'em', 'strike', 'u', 'a', 'br', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'sub', 'sup', 'ul', 'ol', 'li', 'div', 'img', 'video', 'audio' ] }
}
}
}
})(window);
I made a console log just before Aloha.ready and everything is loaded correctly.
So where could be the issue.