I am new to Ruby. I have written a solution in Java
public boolean checkOrder(String input) {
boolean x = false;
for (int i = 0; i < input.length() - 1; i++) {
if (input.charAt(i) < input.charAt(i + 1) || input.charAt(i) == input.charAt(i + 1)) {
x = true;
} else {
return false;
}
}
return x;
}
I want to do the same in ruby how can I convert the same into ruby. Thanks.
def checkOrder(input)
input.chars.sort == input.chars.to_a
end
Variation of Sam's answer, in case you ever want this as a String method:
class String
def sorted?
self.chars.sort == self.chars.to_a
end
end
'abc'.sorted?
'acb'.sorted?
As requested:
def checkOrder(input)
x = false
(input.length-1).times do |i|
if input[i] < input[i+1] or input[i] == input[i+1]
x = true
else
return false
end
end
x
end
Related
I want to select all keyword until by cumulative SUM < X. This does not work because the return true stops the script.
cum_sum = 0
keywords = keywords.select{|k|
cum_sum += k[:contribution]
if cum_sum < top
return true
else
return false
end
}
Block return value is value of the last statement, you can just write:
cum_sum = 0
keywords = keywords.select{|k|
cum_sum += k[:contribution]
cum_sum < top
}
Also there's Enumerable#take_while that's more suitable for your use case
def index() {
//println params
String params_key =params['key']
def c = get_value(params_key)
def resp = ['key': params_key, 'value':c]
render resp as JSON
}
private static hash_conv(String value)
{
def matches = Eval.me(value.replace(':','').replace('{','[').replace('=>',':').replace('#','//').replace('}',']'))
return matches
}
private get_value(String key, default_value=null){
def app_preferences = get_preferences()
def result = app_preferences[key]
if (result == null) {
result = default_value
}
return result
}
private get_preferences(Boolean mobile_app = false){
def all_app_preference = AppPreferences.all
def mapped_value = [:]
def all_app = all_app_preference.each{obj -> mapped_value << get_preference(obj)}
return mapped_value
}
private static get_preference(AppPreferences preference){
def value_type = preference.value_type.toLowerCase()
def val = value_type == 'integer' ? preference.value.toBigInteger() : (value_type == 'boolean' ? (preference.value == 'true' || preference.value == '1' ? true : false):(value_type == 'array' ? preference.value.split(',') : (value_type == 'hash' ? hash_conv(preference.value) :(value_type == 'json' ? new JsonSlurper().parseText(preference.value) : preference.value.toString()))))
def map_value = [:]
map_value[preference.preference_key] = val
return map_value
}
Here I am using AppPreferences domain . It is returning some value on localhost.But when I test it in grails it is returning Null.
My test code as follows:
#TestFor(AppPreferencesController)
#Mock( [AppPreferences] )
//controller.session.SPRING_SECURITY_CONTEXT = [authentication:[principal:[id: 'blah']]]
class AppPreferencesControllerSpec extends Specification {
def setup() {
}
def cleanup() {
}
/*void "test something"() {
expect:"fix me"
true == false
}*/
void test_for_index()
{
when:
controller.session.SPRING_SECURITY_CONTEXT = [authentication:[principal:[id: 'blah']]]
params.key = 'role_to_feature_map'
controller.index()
then:
1 == 1
2 == 2
println response.text
}
}
the response.text is Returning as null.
In local host it is returning a hash value.
Perhaps:
void test_for_index() {
when:
controller.session.SPRING_SECURITY_CONTEXT = [authentication:[principal:[id: 'blah']]]
controller.params.key = 'role_to_feature_map' <-- the params attached to the controller
controller.index()
then:
1 == 1
2 == 2
println response.text
}
Tests typically run against a different database than development, or production. Your test (I assume it is a unit test) will need to mock your AppPreferences domain class. A unit test is just that, only the unit of code being tested. There isn't a Grails application surrounding the tested code.
I would probably add a given: section to the current test, and initialize the entities in the AppPreferences domain class there.
given:
def appPref1 = new AppPreferences("whatever you must set to pass constraints").save(flush:true)
controller.session.SPRING_SECURITY_CONTEXT = [authentication:[principal:[id: 'blah']]]
controller.params.key = 'role_to_feature_map'
when:
controller.index()
then:
1 == 1
2 == 2
println response.text
Personal opinion: The line of code below is unreadable. It would never pass code review where I work. Try a switch statement.
def val = value_type == 'integer' ? preference.value.toBigInteger() : (value_type == 'boolean' ? (preference.value == 'true' || preference.value == '1' ? true : false):(value_type == 'array' ? preference.value.split(',') : (value_type == 'hash' ? hash_conv(preference.value) :(value_type == 'json' ? new JsonSlurper().parseText(preference.value) : preference.value.toString()))))
I am trying to sort but there is a nil. How can i get around this?
Code im useing: (sorting it by name and HPs. in case there is duplicate HPs)
T = { {Name = "Mark", HP = 54, Breed = "Ghost"},
{Name = "Stan", HP = 24, Breed = "Zombie"},
{Name = "Juli", HP = 100, Breed = "Human"},
{ HP = 100, Breed = "Human"}
}
function Sorting(T)
table.sort(T,
function(x,y)
return x.Name < y.Name and x.HP < y.HP
end
)
end
Assuming you want to compare by HP if name isn't available, how about you change the sort comparison function to:
function(x, y)
if x.Name == nil or y.Name == nil then return x.HP < y.HP
else return x.Name < y.Name and x.HP < y.HP
end
end
Your problem is that Name isn't a real key if it's not available all the time.
Want the function to sort the table by HP but if duplicate HPs then sorts by name. When i run this function it just groups the duplicate HPs together in no order by the name.
T = { {Name = "Mark", HP = 54, Breed = "Ghost"}, {Name = "Stan", HP = 24, Breed = "Zombie"}, {Name = "Juli", HP = 100, Breed = "Human"}, { HP = 100, Breed = "Human"} }
function(x, y) if x.Name == nil or y.Name == nil then return x.HP < y.HP else return x.Name < y.Name and x.HP < y.HP end end) end
Try this sort func:
function(x,y)
if x.Name == nil or y.Name == nil then
return x.HP < y.HP
else
return x.HP < y.HP or (x.HP == y.HP and x.Name < y.Name)
end
end
Since you always want differing HPs to be the primary sorting order (and name secondary), you want the HP check to come first in the or clause so that if it differs it'll skip any other checks and just determine based on HP.
I've been using tags in my projects. I was browsing the custom tags on grails.org to find some new tags for my library.
http://www.grails.org/Contribute+a+Tag
I was wondering if people in the StackOverflow community have a favorite custom tag that they would like to share.
I find the DecimalFormat class (and Grails's formatNumber tag by extension) a bit opaque for certain use cases, and I still haven't found a reasonable way to do some pretty basic formatting with it without some ugly pre-processing to generate an appropriate format string. I threw together a simple number formatting tag several months ago which essentially constructs a format string and does some minimal processing to the number itself.
It's not as generic or elegant as I'd like (it's all we needed at the time - it's super basic, but it still keeps some ugly processing out of GSPs), but it should be easy to read, and it's obvious where it could be trivially improved (i.e. making the scaling iterative instead of naive if-elseif slop, allowing the user to pass in custom scaling markers, allowing for a custom number validator as a parameter, etc.).
// Formats a number to 3 significant digits, appending appropriate scale marker
// (k, m, b, t, etc.). Defining var allows you to use a string representation
// of the formatted number anywhere you need it within the tag body, and
// provides the scale as well (in case highlighting or other special formatting
// based upon scale is desired).
def formatNumberScaled = {attrs, body -> // number, prefix, suffix, invalid, var
Double number
String numberString
String scale
try {
number = attrs.'number'.toDouble()
} catch (Exception e) {
number = Double.NaN
}
if (number.isNaN() || number.isInfinite()) {
numberString = scale = attrs.'invalid' ?: "N/A"
} else {
Boolean negative = number < 0d
number = negative ? -number : number
if (number < 1000d) {
scale = ''
} else if (number < 1000000d) {
scale = 'k'
number /= 1000d
} else if (number < 1000000000d) {
scale = 'm'
number /= 1000000d
} else if (number < 1000000000000d) {
scale = 'b'
number /= 1000000000d
} else if (number < 1000000000000000d) {
scale = 't'
number /= 1000000000000d
}
String format
if (number < 10d) {
format = '#.00'
} else if (number < 100d) {
format = '##.0'
} else {
format = '###'
}
format = "'${attrs.'prefix' ?: ''}'${format}'${scale} ${attrs.'suffix' ?: ''}'"
numberString = g.formatNumber('number': negative ? -number : number, 'format': format)
}
// Now, either print the number or output the tag body with
// the appropriate variables set
if (attrs.'var') {
out << body((attrs.'var'): numberString, 'scale': scale)
} else {
out << numberString
}
}
I have a "fmt:relDate" tag that gives you Twitter-like relative dates "3 days ago", "less than 30 seconds ago", etc., with the real time as a tooltip.
The current implementation is basically a gigantic chain of if/then statements with the boundaries that I like. A binary-search based algorithm would be better (in the sense of "more efficient"), and the current implementation has my personal preferences encoded into it, so I'm reluctant to share the tag.
I have a remote paginate tab, that helps me paginate results via ajax. Its an improvement over the default tab and takes in custom arguments.
Here's the code:
class CustomRemotePaginateTagLib {
static namespace = 'myTagLib'
/** * Creates next/previous links to support pagination for the current controller * * <g:paginate total="$ { Account.count() } " /> */
def remotePaginate = {attrs ->
def writer = out
if (attrs.total == null) throwTagError("Tag [remotePaginate] is missing required attribute [total]")
if (attrs.update == null) throwTagError("Tag [remotePaginate] is missing required attribute [update]")
def locale = RequestContextUtils.getLocale(request)
def total = attrs.total.toInteger()
def update = attrs.update
def action = (attrs.action ? attrs.action : (params.action ? params.action : "list"))
def controller = (attrs.controller ? attrs.controller : params.controller)
def offset = params.offset?.toInteger()
def max = params.max?.toInteger()
def maxsteps = (attrs.maxsteps ? attrs.maxsteps.toInteger() : 10)
if (!offset) offset = (attrs.offset ? attrs.offset.toInteger() : 0)
if (!max) max = (attrs.max ? attrs.max.toInteger() : 10)
def linkParams = [offset: offset - max, max: max]
if (params.sort) linkParams.sort = params.sort
if (params.order) linkParams.order = params.order
if (attrs.params) linkParams.putAll(attrs.params)
linkParams['action'] = action
linkParams['controller'] = controller
def linkTagAttrs = [url: "#"]
if (attrs.controller) { linkTagAttrs.controller = attrs.controller }
if (attrs.id != null) { linkTagAttrs.id = attrs.id }
// determine paging variables
def steps = maxsteps > 0
int currentstep = (offset / max) + 1
int firststep = 1
int laststep = Math.round(Math.ceil(total / max))
// display previous link when not on firststep
if (currentstep > firststep) {
linkTagAttrs.class = 'prevLink'
def prevOffset = linkParams.offset
def params = attrs.params ?: []
params.'offset' = prevOffset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) {
(attrs.prev ? attrs.prev : g.message(code: 'default.paginate.prev', default: 'Previous'))
}
}
// display steps when steps are enabled and laststep is not firststep
if (steps && laststep > firststep) {
linkTagAttrs.class = 'step'
// determine begin and endstep paging variables
int beginstep = currentstep - Math.round(maxsteps / 2) + (maxsteps % 2)
int endstep = currentstep + Math.round(maxsteps / 2) - 1
if (beginstep < firststep) {
beginstep = firststep
endstep = maxsteps
}
if (endstep > laststep) {
beginstep = laststep - maxsteps + 1
if (beginstep < firststep) {
beginstep = firststep
}
endstep = laststep
}
// display firststep link when beginstep is not firststep
if (beginstep > firststep) {
linkParams.offset = 0
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) { firststep.toString() }
writer << '<span class="step">..</span>'
}
// display paginate steps
(beginstep..endstep).each {i ->
if (currentstep == i) {
writer << "<span class=\"currentStep\">${i}</span>"
} else {
linkParams.offset = (i - 1) * max
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) { i.toString() }
}
}
// display laststep link when endstep is not laststep
if (endstep < laststep) {
writer << '<span class="step">..</span>'
linkParams.offset = (laststep - 1) * max
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) { laststep.toString() }
}
}
// display next link when not on laststep
if (currentstep < laststep) {
linkTagAttrs.class = 'nextLink'
linkParams.offset = offset + max
def params = attrs.params ?: []
params['offset'] = linkParams.offset
linkTagAttrs.onclick = g.remoteFunction(update: update, action: linkParams.action, controller: linkParams.controller, params: params)
writer << link(linkTagAttrs.clone()) {
(attrs.next ? attrs.next : g.message(code: 'default.paginate.next', default: 'Next'))
}
}
}