Convert Array of Arrays into JSON - arrays

I have an array of arrays that I'd like to convert into json and output within another array. I have the following array:
weekdays = [["Monday",2],["Tuesday",4],["Thursday",5]]
I would like to include this array within a JSON output like so:
json_output = { :results => weekdays.count, :data => weekdays }
Right now I get this, which just doesn't look right as there are not curly brackets around the "data" field...
{
"results": 2,
"data": [
["Monday", 2],
["Tuesday", 4],
["Thursday", 5]
]
}
Any help would be great!

The output is correct. Curly brackets are around hashes, but your data attribute is a nested array.
If you want to convert a nested array into a hash, just call to_h on it:
{ :results => weekdays.count, :data => weekdays.to_h }

Better to convert it to hash manually.
weekdays = [["Monday",2],["Tuesday",4],["Thursday",5]]
hash_weekdays = Hash.new
weekdays.each do |item|
hash_weekdays[item[0]] = item[1]
end
hash_weekdays #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}

Related

How to count all data item array in laravel

How to count all data item array in laravel, please help me!. Thank you so much!
Output: 8
reduce()
The reduce method reduces the collection to a single value, passing
the result of each iteration into the subsequent iteration:
$count = collect([
(object)["views_back" => 3],
(object)["views_back" => 5]
])->reduce(function ($carry, $item) {
return $carry + $item->views_back;
});
var_export($count); // 8
Addendum
Alternatively, using native/vanilla PHP:
$count = array_sum(array_column([
(object)["views_back" => 3],
(object)["views_back" => 5]
], "views_back"));
var_export($count); // 8
When working with arrays in Laravel, it can be helpful to convert them to a Collection which provides some helper methods for arrays.
If all you want is the number of elements in the array use count.
If you want the sum of the views_back elements, use reduce.
$array = [
[
'views_back' => 3,
],
[
'views_back' => 5,
]
];
$count = collect($array)->count();
$sum = collect($array)->reduce(function ($carry, $element) {
return $carry + $element['views_back'];
});
dd($count, $sum);
In the above $count is 2 and $sum is 8.
If your original data is json (as you've used a json tag), you will need to convet the data to an array first:
$array = json_decode($json, true);
You can use laravel collection method sum() method to write smaller code and make it easier to read.
$data = [
(object)["views_back" => 3],
(object)["views_back" => 5]
];
collect($data)->sum('views_back');
Converting array to collection can be CPU costly depending on the size of the input array. In that case #steven7mwesigwa vanilla PHP answer would be the best solution.

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);

Converting array to json in Ruby (Puppet, facter)

I'm writing a fact for Puppet in Ruby. I have an array
array = [[["User", "Username"], ["Date", "16.12.2014"]], [["User1", "Username1"], ["Date1", "17.12.2014"]]]
I want to convert it to json. I tried to convert it to hash first, but doing like this in Linux
array.each do |userarr|
winusers = Hash[userarr.map! { |pair| [pair[0], pair[1]] } ]
end
I get only the this one [["User1", "Username1"], ["Date1", "17.12.2014"]] pair converted. Doing like this:
array.each do |userarr|
winusers = Hash[userarr.map! { |pair| [pair[0], pair[1]] } ]
winusersa << winusers
end
I get an array of hashes. Coverting it to json winusersa.to_json on Linux I get an array of json format text, on Puppet (facter in fact) I get only the first pair converted. Why in Puppet fact it doesn't work? How to convert that array to get all pairs well formated?
Try this one
array.flatten(1).each_slice(2).map(&:to_h)
=> [{"User"=>"Username", "Date"=>"16.12.2014"}, {"User1"=>"Username1", "Date1"=>"17.12.2014"}]
And then, as an hash, you can easily call to_json
You've already got your Array in the form that the ruby Hash#[] method can consume. I think all you need is this:
% pry
[1] pry(main)> require 'json'
[2] pry(main)> a = [[["User", "Username"], ["Date", "16.12.2014"]], [["User1", "Username1"], ["Date1", "17.12.2014"]]]
[3] pry(main)> puts JSON.pretty_generate(a.map { |e| Hash[e] })
[
{
"User": "Username",
"Date": "16.12.2014"
},
{
"User1": "Username1",
"Date1": "17.12.2014"
}
]
Require 'facter' #if you have facter as gem to test locally require 'json'
array = [
[
["User", "Username"],
["Date", "16.12.2014"]
],
[
["User1", "Username1"],
["Date1", "17.12.2014"]
]
]
put JSON.pretty_generate(JSON.parse(array.to_json))

ruby sorting hashes inside array

I have an array of hashes that I would like to sort based on the :reference values. But some of the elements within the array do not have a :reference key and therefore cannot be sorted. Is there a way to ignore this field and just sort the hash elements that contain this key?
I've tried the following approach but I'm getting an argument error
ArgumentError: comparison of NilClass with String failed
sort_by at org/jruby/RubyEnumerable.java:503
arr1 = [{:reference=> "F123",
:name=> "test4"
},
{
:reference=> "ZA4",
:name=> "test3"
},
{
:reference=> "A43",
:name=> "test2"
},
{
:name=> "test1"
},
{
:name=> "homework1"
}]
arr1 = arr1.sort_by { |hash| hash[:reference] }
puts arr1
The correct output should look like this :
=> arr1= [
{:reference=>"A43", :name=>"test2"},
{:reference=>"F123", :name=>"test4"},
{:reference=>"ZA4", :name=>"test3"},
{:name=> "test1"},
{:name=> "homework1"}
]
You can only sort on values that can be compared, so if you've got values of different types it's best to convert them to the same type first. A simple work-around is to convert to string:
arr1.sort_by { |hash| hash[:reference].to_s }
You can also assign a default:
arr1.sort_by { |hash| hash[:reference] || '' }
Edit: If you want the nil values sorted last:
arr1.sort_by { |hash| [ hash[:reference] ? 0 : 1, hash[:reference].to_s ] }
If you don't mind temporary variables, you could split the array into two arrays, one containing hashes with :reference and the other those without:
with_ref, without_ref = arr1.partition { |h| h[:reference] }
Then sort the first one:
with_ref.sort_by! { |h| h[:reference] }
And finally concatenate both arrays:
arr1 = with_ref + without_ref

Generate from two ruby arrays an appropriate JSON output

I have two simple ruby arrays and a JSON string mapping the elements of the first array to the elements of the second array:
keys = [:key0, :key1, :key2]
values = [:value0, :value1, :value2]
jsonString = {keys[0] => values[0], keys[1] => values[1], keys[2] => values[2]}
Writing this to a file:
file.write(JSON.pretty_generate(jsonString))
results into a nicely printed json object:
{
"key0": "value0",
"key1": "value1",
"key2": "value2"
}
But how can I generate the same output of two much bigger arrays without listing all these elements explicitly?
I just need something like
jsonString = {keys => values}
but this produces a different output:
{
"[:key0, :key1, :key2]":
[
"value0",
"value1",
"value2"
]
}
How can I map the two without looping over both?
array = keys.zip(values)
#=> [[:key0, :value0], [:key1, :value1], [:key2, :value2]]
Array#zip merges elements of self to the corresponding elements of the argument array and you get an array of arrays. This you can convert into a hash ...
hash = array.to_h
# => {:key0=>:value0, :key1=>:value1, :key2=>:value2}
... and the hash you can turn into a json string.
jsonString = JSON.pretty_generate(hash)
puts jsonString
#{
# "key0": "value0",
# "key1": "value1",
# "key2": "value2"
#}
Use Array#zip to make pairs of values and then make hash of them:
keys = [:key0, :key1, :key2]
values = [:value0, :value1, :value2]
Hash[keys.zip values]
# => {:key0=>:value0, :key1=>:value1, :key2=>:value2}

Resources