Converting Ruby array of array into a hash - arrays

I have an array of arrays as below :
[
["2021-07-26T11:38:42.000+09:00", 1127167],
["2021-08-26T11:38:42.000+09:00", 1127170],
["2021-09-26T11:38:42.000+09:00", 1127161],
["2021-07-25T11:38:42.000+09:00", 1127177],
["2021-08-27T11:38:42.000+09:00", 1127104]
]
What i want to have as the output :
{
"2021-July" => [["2021-07-26T11:38:42.000+09:00", 1127167],["2021-07-25T11:38:42.000+09:00", 1127177]],
"2021-August" => [["2021-08-26T11:38:42.000+09:00", 112717],["2021-08-27T11:38:42.000+09:00", 112710]],
"2021-September" => ["2021-09-26T11:38:42.000+09:00", 112716]
}
I want to create the hash key year-month format based on the date value in each array element. What would be the easiest way to do this?

use group_by
date_array = [["2021-07-26T11:38:42.000+09:00", 1127167],["2021-08-26T11:38:42.000+09:00", 112717],["2021-09-26T11:38:42.000+09:00", 112716],["2021-07-25T11:38:42.000+09:00", 1127177],["2021-08-27T11:38:42.000+09:00", 112710]]
result = date_array.group_by{ |e| Date.parse(e.first).strftime("%Y-%B") }

date_array = [["2021-07-26T11:38:42.000+09:00", 1127167],["2021-08-26T11:38:42.000+09:00", 112717],["2021-09-26T11:38:42.000+09:00", 112716],["2021-07-25T11:38:42.000+09:00", 1127177],["2021-08-27T11:38:42.000+09:00", 112710]]
result_date_hash = Hash.new([])
date_array.each do |date|
formatted_date = Date.parse(date.first).strftime("%Y-%B")
result_date_hash[formatted_date] += date
end
Output:
puts result_date_hash
=>
{"2021-July"=>["2021-07-26T11:38:42.000+09:00", 1127167, "2021-07-25T11:38:42.000+09:00", 1127177],
"2021-August"=>["2021-08-26T11:38:42.000+09:00", 1127170, "2021-08-27T11:38:42.000+09:00", 1127104],
"2021-September"=>["2021-09-26T11:38:42.000+09:00", 1127161]}

Related

Convert Laravel array collection to array

I was updating may images array which is found in following format:
[
"d756d3d2b9dac72449a6a6926534558a.jpg",
"b607aa5b2fd58dd860bfb55619389982.jpg",
"f937c8fddbe66ab03c563f16d5cfa50c.jpg"
]
So to delete a single image d756d3d2b9dac72449a6a6926534558a.jpg from this array column I used the filter method like below:
$collection = collect($imageColumn)->filter(
function ($valueTobeDeleted) use ($array) {
return !in_array($valueTobeDeleted, $array);
}
);
so after filter I wan to update my database with the new collection, but the new collection is in a map format like below
array:2 [
1 => "b607aa5b2fd58dd860bfb55619389982.jpg"
2 => "f937c8fddbe66ab03c563f16d5cfa50c.jpg"
]
the problem is i don't need those keys 1, and 2 my expectation was
array:2 [
"b607aa5b2fd58dd860bfb55619389982.jpg"
"f937c8fddbe66ab03c563f16d5cfa50c.jpg"
]
How can I achieve my expectation? How can I convert them to array?
Because you are using a Collection, you can do ->values() at the end so you convert all keys into integer keys and beginning from 0, like a normal non-associative array:
$collection = collect($imageColumn)->filter(
function ($valueTobeDeleted) use ($array) {
return !in_array($valueTobeDeleted, $array);
}
)
->values();
In order to re-index an array, you can use the array_values PHP function:
$arr = array_values($arr);
This will fix the keys.
Use array_values to get a an array of that associatve array.
$collection = collect($imageColumn)->
$filtered = filter(function ($valueTobeDeleted) use ($array) {
return !in_array($valueTobeDeleted, $array);
});
$filtered = array_values($filtered);

how to merge values in a list of map in ruby

say I have data structure like List< MAP< String, List>>, I only want to keep the List in map's value,
Like, I want to convert following example:
x = [{"key1" => ["list1", "list1"]}, {"key2" => ["list2", "list2"]},
{"key3" => ["list3", "list3"]}]
to:
y = [["list1", "list1"], ["list2", "list2"], ["list3", "list3"]]
Is there any quick way to do this? Thanks
The quickest thing that comes to mind is to leverage flat_map.
x = [ { "key1" => ["list1", "list1"] },
{ "key2" => ["list2", "list2"] },
{ "key3" => ["list3", "list3"] }]
y = x.flat_map(&:values)
=> [["list1", "list1"], ["list2", "list2"], ["list3", "list3"]]
flat_map is an instance method on Enumerable (https://ruby-doc.org/core-2.6.3/Enumerable.html#method-i-flat_map)
values is an instance method on Hash (https://ruby-doc.org/core-2.6.3/Hash.html#method-i-values)
If you only have 1 key in those hashes then you can do it like this:
y = x.map { |h| h.values[0] }

Unique values in MongoDb array

I am trying find unique ObjectIds from monogdb ObjectId array using filter. For some reason I am not getting unique array back. Is there is some other way to get unique array back ?
var objIds = [ 5ad3509fbb426a4f4a382754,
5ad3509fbb426a4f4a382752,
5ad3509fbb426a4f4a382754,
5ad3509fbb426a4f4a382751
]
Here is the filter code
objIds = objIds.filter((x, i, a) => a.indexOf(x) == i)
I am expecting following array after filter
[ 5ad3509fbb426a4f4a382754,
5ad3509fbb426a4f4a382752,
5ad3509fbb426a4f4a382751
]
If you are passing in an array and the elements inside the array is a string then this should work.
function getUniqueValues(arr) {
return arr.filter((e, i) => arr.indexOf(e) === i)
}
you can use lodash's uniq method to do this easily.
const { uniq } = require("lodash");
var objIds = [
"5ad3509fbb426a4f4a382754",
"5ad3509fbb426a4f4a382752",
"5ad3509fbb426a4f4a382754",
"5ad3509fbb426a4f4a382751"
];
console.log(uniq(objIds));
will give the following output
[ '5ad3509fbb426a4f4a382754',
'5ad3509fbb426a4f4a382752',
'5ad3509fbb426a4f4a382751' ]

String substitution for key value pairs in array

I'm trying to message some data of key values in arrays but stumped.
Here's what's in my array:
data = [ "name=abc", "title=analyst", "group=IT", "id=123"]
The mapping that I'm looking to translate:
mapping = { "name" => "EmployeeName", "title" => "JobTitle", "group" => "BusinessGroup", "id" => "EmployeeID"}
The expected result that I'm after:
data = [ "EmployeeName=abc", "JobTitle=analyst", "BusinessGroup=IT", "EmployeeID=123"]
data.map {|s| s.sub /\w+/, mapping }
# => ["EmployeeName=abc", "JobTitle=analyst", "BusinessGroup=IT", "EmployeeID=123"]
data.map { |str| str.split(/\s*=\s*/).tap { |k,_| k.replace(mapping[k]) }.join('=') }
#=> ["EmployeeName=abc", "JobTitle=analyst", "BusinessGroup=IT", "EmployeeID=123"]
I've split on /\s*=\s*/, rather than "=", in case there are any spaces before or after =.
Given your data array and mapping hash, you can do the following using Array#map:
data.map do |i|
key, value = i.split('=')
"#{mapping[key]}=#{value}"
end
# => ["EmployeeName=abc", "JobTitle=analyst", "BusinessGroup=IT", # "EmployeeID=123"]
> data.map{|a| a.split("=")}.map{|e| mapping.has_key?(e[0]) ? "#{e[0] = mapping[e[0]]}=#{e[1]}" : "#{e[0]}\=#{e[1]}"}
=> ["EmployeeName=abc", "JobTitle=analyst", "BusinessGroup=IT", "EmployeeID=123"]

Merge nested hash without overwritting in Ruby

After checking this Ruby convert array to nested hash and other sites I am not able to achieve the following convertion:
I have this:
{"a"=>"text"}
{"b"=>{"x"=>"hola"}}
{"b"=>{"y"=>"pto"}
}
and I want to obtain:
{"a"=>text,
b=>{"x" => "hola",
"y" => "pto"
}
}
Until now the code seems like this:
tm =[[["a"],"text"],[["b","x"],"hola"],[["b","y"],"pto"]]
q = {}
tm.each do |l|
q = l[0].reverse.inject(l[1]) { |p, n| { n => p } }
i += 1
end
I tried with merge, but it overwrites the keys!. I tried also this How can I merge two hashes without overwritten duplicate keys in Ruby? but it keeps overwritting.
Update:
How can I do it for an undefined nested hash (level) ? hash[key1][key2][key3]... = "value"
{"a"=>"text"},
{"b"=>{"x"=>"hola"},
{"b"=>{"y"=>"pto"},
{"c"=>{"g"=>{"k" => "test1"}},
...
}
You could use merge with a block to tell Ruby how to handle duplicate keys:
a = {"a"=>"text"}
b = {"b"=>{"x"=>"hola"}}
c = {"b"=>{"y"=>"pto"}}
a.merge(b).merge(c) { |key, left, right| left.merge(right) }
#=> {"a"=>"text", "b"=>{"x"=>"hola", "y"=>"pto"}}
For Rails there is the deep_merge function for ActiveSupport that does exactly what you ask for.
You can implement the same for yourself as follows:
class ::Hash
def deep_merge(second)
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
self.merge(second, &merger)
end
end
Now,
h1 = {"a"=>"text"}
h2 = {"b"=>{"x"=>"hola"}}
h3 = {"b"=>{"y"=>"pto"}}
h1.deep_merge(h2).deep_merge(h3)
# => {"a"=>"text", "b"=>{"x"=>"hola", "y"=>"pto"}}

Resources