IFS formula with date types as conditions - date

I have two different date types in my table: the first is simple YYYY-MM-DD, the second contains the week number and year.
How is it possible to build an IFS formula, where these two date types are conditions? Like:
=IFS(A1="YYYY-MM-DD", "A", A1="WWYYYY", "B")

You may simply use following formula:
=IFS(LEN(A1)=10,"A",len(A1)=6,"B")

I didn't see Google Sheets Data Format WWYYYY then I assumed that you have text values. If it's true then you can try REGEXMATCH
=IFS(REGEXMATCH(J8,"\d{4}-\d{2}-\d{2}"), "A",REGEXMATCH(J8,"\d{6}"), "B")
But for me I will not save Dates as text. It requires a script
/**
*
* #customformula
*/
function PATTERN_EXTRACTOR(pattern, a1Notations) {
var patt = new RegExp(pattern, 'gi');
var range = SpreadsheetApp.getActiveSheet().getRange(a1Notations);
return range.getDisplayValues().map(function(row) {
return row.map(function(cell) {
return cell.replace(patt,'X');
});
});
}
Getting pattern
=PATTERN_EXTRACTOR("\d",CELL("address",I8))
Resolve conditions
=IFS(I10="XXXX-XX-XX", "A",I10="XXXXXX", "B")

this could work too:
=ARRAYFORMULA(IF(IFERROR(DATEVALUE(A1:A5)), "A",
IF(ISNUMBER(A1:A5), "B", )))

Related

How to override Ag Grid QuickFilter to receive exact match results?

By default Ag Grid Quick Filter function return rows that contains search string. For example if I type "30 June" in the searchbox, quick filter will also return rows that contains "30 cars were sold by 2 June" text. How can I override default behavior to receive only rows that exactly match my search string?
What I did was the following:
In the search itself, I removed the spaces from the search criteria:
this.gridApi.setQuickFilter(event.toLowerCase().replace(" ", ""));
In each column that I wanted an exact match, I added this code in the column definition:
getQuickFilterText: (params) => { return params.value && params.value.toLowerCase().replace(" ", "");}
(That is the override method for search. See here for more details: https://www.ag-grid.com/angular-data-grid/filter-quick/)
It seems to be working for me.
To achieve the exact match results column wise, You have to do these two things :
Remove cacheQuickFilter property from your default column definition object in gridOptions as caching convert all the columns data into a string separated by backward slash. That's the reason it will not be able to search column by column.
Add getQuickFilterText function in each column definition and add a condition for a exact match else return an empty string.
getQuickFilterText: params => {
return (params.value === <quick filter value>) ? params.value : ''
}
Now the tricky part here is how to access quick filter value inside getQuickFilterText function. You can achieve this in two ways :
Assign an id to quick filter search element and then access it's value using document.getElementById('quick-filter').value
Store the quick filter search value on change and put into a store state or service and then access that inside getQuickFilterText function.

How to aggregate same column multiple times in daru

I want to get grouped aggregated data, but running into a problem with the aggregating same column with multiple functions.
Basically, I want to know if there is a way to rename an aggregated column, so it doesn't rewrite.
Here is my code
df = Daru::DataFrame.from_activerecord(active_record,
*%i[jobs.id jobs.demand_created_at jobs.quality_rating jobs.service_rating jobs.value_rating SC.name D.czso_region_id])
df.vectors = Daru::Index.new(%i[job_id demand_created_at quality_rating service_rating value_rating specific_category_name region_id])
# computed columns
df[:avg_rating] = ((df[:quality_rating] + df[:service_rating] + df[:value_rating]) / 3.0)
df[:broad_region_id] = df[:region_id].recode { |i| i[0...-1]}
df_grouped = df.group_by([:specific_category_name, :broad_region_id, :job_id])
df_grouped.aggregate(avg_rating: :mean, job_id: :count).aggregate(avg_rating: :mean, job_id: :count)
I'm having problem here:
df_grouped.aggregate(avg_rating: :mean, job_id: :count).aggregate(avg_rating: :mean, job_id: :count)
Basically, I want to write something like this (for example):
df_grouped.aggregate(avg_rating: :mean, avg_rating: :std)
However, this only generates one column named avg_rating and error
(irb):124: warning: key :avg_rating is duplicated and overwritten on line 124
Is there a way to rename aggregated column?
The only idea I have is to duplicate columns, but that seems like a very hacky solution.
Well, I finally found the answer here.
Agreggation of grouped data can be done like this:
df.group_by(:a).aggregate(
avg_d: ->(df) { df[:d].mean },
sum_c: ->(df) { df[:c].sum },
avg_of_c: ->(df) { df[:c].mean },
size_b_with_lambda: ->(grouped){ grouped[:b].size},
uniq_b_with_proc: proc {|grouped| grouped[:b].uniq.size }
)
which solves all my issues

Equivalent of StructKeyList() for struct value

StructKeyList() will give me list of struct key with comma delimited. Now I need to get struct value with comma delimited. Right now this is what I'm doing to get value
<cfloop collection="#form#" item="key" >
#form[key]#,
</cfloop>
How can I get list of value from struct without loop? Thanks in advance.
I go through your problem. As per my knowledge is not possible to get list of value in structure within single functions. We have to loop the key and get the value of each. But I can give a solution for to get struct value with comma delimited.
<cfset strNew = {"a":"10","b":20,"c":30}>
Here strNew is my sample structure.
<cfset myList = ''>
<cfloop collection="#strNew#" item="key" >
<cfset myList = listappend(myList,structfind(strNew,key))>
</cfloop>
<cfdump var="#myList#" />
Here I've loop over the structure keys and find the value of an particular key and append that in to and list by using listappend and structfind functions.
So you no need to put like #structure[key]#,In your end of comma(,) is also added the last value of key too. For example your code should return 10,20,30,.
So you no need to do like that. use structfind and listappend you can avoid end of the comma also. Hope it's help you.
Since you're using CF2016, if you want to avoid a loop, you can always use one of the higher-order functions like reduce().
fields = formScope.reduce( function(result, key, value) {
result.append(value) ;
return result ;
}, [] ) ;
This takes the struct of your form scope (formscope) and uses reduce() to step through it and take it down to a single value (which is the struct values turned into an array). Then we make the returned array into a list.
writeDump( fields.toList() )
My full test code is at https://trycf.com/gist/f00cc62cd4631f44070faf8008e6788f/acf2016?theme=monokai
<cfscript>
formScope = {
empty1 : "" ,
fieldl : "text1" ,
field2 : "text2" ,
empty2 : "" ,
field3 : "text3" ,
field4 : "text4" ,
empty3 : ""
} ;
fields = formScope?.reduce( function(result, key, value) {
len(value) ? result.append(value) : "" ;
return result ;
}, [] ) ;
writeDump( fields?.toList() ?: "Form doesn't exist." ) ;
</cfscript>
Giving us: text2,text3,text4,text1.
formScope is my simulated version of the form fields that would be passed to this page. I use mostly the member function versions of StructReduce, ArrayAppend and ArrayToList. I also use the initialVal optional parameter to initialize the reduction's result value as an array. I check that the value has a length (I could also trim if needed) before I insert a row in the array, allowing me to remove empty elements from my final list. I also use the safe navigation operator (?.) to do some basic validation to make sure the elements exist (like if the form didn't pass or the reduction produced invalid results) and to make it more error-resistant.
NOTE: I believe that can be taken back to be compatible with CF11, when ArrayReduce was introduced.
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-s/structreduce.html
http://ryanguill.com/functional/higher-order-functions/2016/05/18/higher-order-functions.html
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arraytolist.html

Trying to get month from date in laravel (and postgres extract not working)

I'm making my first laravel project, using postgres, and I'd like to be able to access all the people with a birthday this month (my people table has a birthdate field that's a date). I can use extract to get these records from the database, like so:
select * from people
where extract (month from birthdate) = 11;
But when I try a few different ways in my controller I get 'unknown column' errors:
$birthday_people = DB::table('people')
->where ("extract(month from birthdate)", "=", "11")
->get();
(I'll ultimately adjust it to compare with Carbon::now()->month, and use the model Person::all(), but until I get some results coming through I'm going as simple as possible)
Is there a special way to get the month from a date in laravel?
Update: I'm using a scope now in my Person model. I can get person results to come through when I give it an exact date:
public function scopeBirthdays($query)
{
return $query->where('birthdate', '=', '1947-11-02');
}
And I can get results back for month if I do it this way, but the catch is it doesn't seem to know it's a collection of People anymore (I can't access person columns when I display it out and I can't chain other scopes):
public function scopeBirthdays($query)
{
return $query->whereRaw('extract(month from birthdate) = ?', ['11'])->get();
}
Laravel's query builder offers 'whereMonth'- (seems the most right), but it gave me an 'undefined function' error until I put the bool on the end, and now the current error suggests that it's interpretting number of months instead of which one(?):
public function scopeBirthdays($query)
{
return $query->whereMonth('birthdate', '=', Carbon::today()->month, true);
}
I get:
Syntax error: 7 ERROR: syntax error at or near "month"
LINE 1: select * from "people" where 1 month("birthdate") = $1
^ (SQL: select * from "people" where 1 month("birthdate") = 11)
Final update: I was able to get results back (that were correctly interpretted as people) by using whereRaw in my scope:
public function scopeBirthdays($query)
{
return $query->whereRaw('extract(month from birthdate) = ?', [Carbon::today()->month])->orderBy ('birthdate', 'asc');
}
Thanks, everyone!
based on previous question try:
$birthday_people = DB::table('people')
->whereRaw("extract(month from birthdate)", "=", "11")
->get();
You can set is as relationship
public function custom(){
return $this->hasMany('App\Models\People')->whereRaw("extract(month from birthdate)", "=", "11");
}
You could try something like this. It will return as an instance of App\People so you will be able to use your eloquent functions still.
public function scopeBirthdays($query)
{
return $query->where('birthdate', 'LIKE', Carbon::today()->year . '-'.Carbon::today()->month.'%');
}
I don't have much experience with Carbon, I'm assuming that Carbon::today() will return an object with the year, month, and date.

How to use nest in d3 to group using the 'month' as key, but my csv file contains the whole date?

var data = d3.nest()
.key(function(d) { return d.date;})
.rollup(function(d) {
return d3.sum(d, function(g) {return g.something; });
}).entries(csv_data);
using this code above I can group by date which is in the format yyyy-mm-dd , but I want to group using the month as key. How do I do this ?
You can use the builtin method d3.timeMonth() to get the first day of the month for a date like:
d3.nest()
.key(function(d){ return d3.timeMonth(d.date); });
If d.date is not already a javascript Date object you have to first parse it to be one.
var date_format = d3.timeFormat("%Y-%m-%d");
csv_data.forEach(function(d, i) {
d.date = date_format.parse(d.date);
};
You need to change the key function to return the value you want to nest by. In most cases, the key function just returns a property of the data object (like d.date), but in your case the function will require a little more calculation.
If your date is stored as a string of the format "yyyy-mm-dd" you have two options for extracting the month: either
use regular expressions to extract the portion of the string in between the "-" characters, or
convert it to a date object and use date methods to extract a component of the date.
Browsers differ in which date formats they can convert using the native Javascript new Date(string) constructor, so if you're using date objects you may want to use a d3 date format function's format.parse(string) method to be sure of consistent results.