Working with Transpose functions result in error


Working with Transpose functions result in error



consider the following array


arr = [["Locator", "Test1", "string1","string2","string3","string4"],
["$LogicalName", "Create Individual Contact","value1","value2"]]



Desired result:


[Test1=>{"string1"=>"value1","string2"=>"value2","string3"=>"","string4"=>""}]



When I do transpose, it gives me the error by saying second element of the array is not the length of the first element in the array,


Uncaught exception: element size differs (2 should be 4)



so is there any to add empty string in the place where there is no element and can perform the transpose and then create the hash as I have given above? The array may consist of many elements with different length but according to the size of the first element in the array, every other inner array has to change by inserting empty string and then I can do the transpose. Is there any way?





That data structure doesn't sound very suitable for transpose. You may get better answers by describing the result you want instead of a particular method you want to call.
– matthewd
Jul 1 at 10:29


transpose





@matthewd Hi check it out now.
– Rajagopalan
Jul 1 at 10:41





Your desired result is not a Ruby object. Do you mean it to be a hash (rather than an array)? btw, note that in my editing of your question (which I did mainly to avoid the need for readers to scroll horizontally to read the code) I assigned a variable (arr) to the input array. You should do that routinely to allow readers to reference such nvariables in answers and comments without having to define them. Lastly, do we know "Test1" is to be the key, arr[0][1] is to be the key, or something else? Similar questions about about "stringX" and "valueX".
– Cary Swoveland
Jul 1 at 18:41



arr


"Test1"


arr[0][1]


"stringX"


"valueX"




3 Answers
3



It sounds like you might want Enumerable#zip:


Enumerable#zip


headers, *data_rows = input_data
headers.zip(*data_rows)
# => [["Locator", "$LogicalName"], ["Test1", "Create Individual Contact"],
# ["string1", "value1"], ["string2", "value2"], ["string3", nil], ["string4", nil]]





If you really need the blanks to be "", that's an easy map away... but I'd argue that nil is a more idiomatic choice of value to fill the gaps.
– matthewd
Jul 1 at 10:54


""


map


nil





That's absolute what I want, But also I want one more adding, that's this p result[1..-1].map{|dataRow| result[0].zip(dataRow).to_h}
– Rajagopalan
Jul 1 at 11:16


p result[1..-1].map{|dataRow| result[0].zip(dataRow).to_h}



If you wish to transpose an array of arrays, each element of the array must be the same size. Here you would need to do something like the following.


arr = [["Locator", "Test1", "string1","string2","string3","string4"],
["$LogicalName", "Create Individual Contact","value1","value2"]]

keys, vals = arr
#=> [["Locator", "Test1", "string1", "string2", "string3", "string4"],
# ["$LogicalName", "Create Individual Contact", "value1", "value2"]]
idx = keys.index("Test1") + 1
#=> 2

{ "Test1" => [keys[idx..-1],
vals[idx..-1].
concat(['']*(keys.size - vals.size))].
transpose.
to_h }
#=> {"Test1"=>{"string1"=>"value1", "string2"=>"value2", "string3"=>"", "string4"=>""}}



It is not strictly necessary to define the variables keys and vals, but that avoids the need to create those arrays multiple times. It reads better as well, in my opinion.


keys


vals



The steps are as follows. Note keys.size #=> 6 and vals.size #=> 4.


keys.size #=> 6


vals.size #=> 4


a = vals[idx..-1]
#=> vals[2..-1]
#=> ["value1", "value2"]
b = [""]*(keys.size - vals.size)
#=> [""]*(4 - 2)
#=> ["", ""]
c = a.concat(b)
#=> ["value1", "value2", "", ""]
d = keys[idx..-1]
#=> ["string1", "string2", "string3", "string4"]
e = [d, c].transpose
#=> [["string1", "value1"], ["string2", "value2"], ["string3", ""], ["string4", ""]]
f = e.to_h
#=> {"string1"=>"value1", "string2"=>"value2", "string3"=>"", "string4"=>""}
f = e.to_h
#=> { "Test1" => f }





Excellent answer! Test1 should not be hard-coded but I will take it from array.
– Rajagopalan
Jul 1 at 21:54




Find the longest Element in your Array and make sure every other element has the same length - loop and add maxLength - element(i).length amount of "" elements.


maxLength - element(i).length






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to add background colour in existing image using Swift?

Moria Casán

How to make file upload 'Required' in Contact Form 7?