Skip to content

Instantly share code, notes, and snippets.

@jca02266
Created November 3, 2021 01:16
Show Gist options
  • Save jca02266/531b48a93de6cf0baf2053b9949c5361 to your computer and use it in GitHub Desktop.
Save jca02266/531b48a93de6cf0baf2053b9949c5361 to your computer and use it in GitHub Desktop.
JSON transform example
person1
a1
b1
2021-11-01 - 2021-11-07 (2021-11-01 - 2021-11-03): c1
2021-11-01 - 2021-11-07 (2021-11-02 - ): c2
person2
a1
b2
2021-11-01 - 2021-11-07 ( - ): c2
b3
2021-11-01 - 2021-11-07 ( - ): c3
require "json"
Task = Struct.new(:task1, :task2, :task3, :task4,
:assignee1, :assignee2, :assignee3,
:startDate, :endDate, :actStartDate, :actEndDate) do
def self.new(hash)
obj = self.allocate
hash.each_with_object(obj) {|(k, v), o| o[k] = v}
obj
end
def to_s
"#{self.startDate} - #{self.endDate} (#{self.actStartDate} - #{self.actEndDate}): #{self.task3}"
end
end
class TaskNotifier
def initialize(file)
tasks_json = File.read(file)
@tasks = JSON.load(tasks_json)["data"].map {|hash|
Task.new hash
}
@root = _treeize([:assignee1, :task1, :task2], @tasks)
end
def _treeize(keys, tasks)
k = keys.first
o = tasks.group_by {|o| o[keys.first]}
if keys.size > 1
o.each {|k, v|
o[k] = _treeize(keys.drop(1), v)
}
end
return o
end
def walk(&block)
_walk(@root, 0, &block)
end
def _walk(node, level = 0, &block)
if Hash === node
# Tree
node.each {|k, v|
block.call :node, level, k
_walk(v, level + 1, &block)
}
else
# Leaf
node.each {|v|
block.call :leaf, level, v
}
end
end
end
def main(out = STDOUT)
obj = TaskNotifier.new("tasks.json")
obj.walk do |type, level, value|
out.print " " * level, value
out.puts
end
end
if __FILE__ == $0
main
end
{
"projectId": "12345",
"data": [
{"task1": "a1", "task2": "b1", "task3": "c1", "task4": "",
"assignee1": "person1", "assignee2": "person2", "assignee3": "",
"startDate": "2021-11-01", "endDate": "2021-11-07", "actStartDate": "2021-11-01", "actEndDate": "2021-11-03"},
{"task1": "a1", "task2": "b1", "task3": "c2", "task4": "",
"assignee1": "person1", "assignee2": "person2", "assignee3": "",
"startDate": "2021-11-01", "endDate": "2021-11-07", "actStartDate": "2021-11-02", "actEndDate": ""},
{"task1": "a1", "task2": "b2", "task3": "c2", "task4": "",
"assignee1": "person2", "assignee2": "", "assignee3": "",
"startDate": "2021-11-01", "endDate": "2021-11-07", "actStartDate": "", "actEndDate": ""},
{"task1": "a1", "task2": "b3", "task3": "c3", "task4": "",
"assignee1": "person2", "assignee2": "", "assignee3": "",
"startDate": "2021-11-01", "endDate": "2021-11-07", "actStartDate": "", "actEndDate": ""}
]
}
require "minitest/autorun"
require_relative 'task_notifier'
$expect = File.read('expect.txt')
class Test < MiniTest::Test
def setup
require "stringio"
@out = StringIO.new
main @out
@out.rewind
end
def test_
assert_equal $expect, @out.read
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment