C#, LINQでGroupByしたコレクション内の数値の合計を得る
はじめに
開発環境諸々
- Microsoft Visual Studio Community 2019
- Version 16.5.4
- Microsoft .NET Framework
- Version 4.8.03752
- プロジェクトの種類
- Console App(.NET Core3.1)
名前空間
using System; using System.Linq;
集計対象
var hoges = new[] { new {Name = "a", Score = 1}, new {Name = "a", Score = 2}, new {Name = "a", Score = 3}, new {Name = "b", Score = 4}, new {Name = "b", Score = 5}, };
GroupByでまとめたりSumったり
var query = hoges
.GroupBy(item => item.Name)
.Select(item => new
{
Name = item.Key,
TotalScore = item.Sum(x => x.Score)
});
結果確認
foreach(var item in query) { Console.WriteLine(item); }
実行結果
{ Name = a, TotalScore = 6 } { Name = b, TotalScore = 9 }
所感
LINQ便利!何かしら集計するときに使える!
Google Chrome Extensions, Hello Extensions!と表示する
はじめに
Google Chrome Extensionsのチュートリアルを試す。
Google Chrome Extensionsはmanifest.json
と任意の名称のhtml
ファイルを1つ、アイコン用のpng
ファイルを1つ用意する。
動作環境
- Web Browser
- Google Chrome
- 81.0.4044.113(Official Build)(64bit)
- Google Chrome
開発環境
- Editor
- Visual Studio Code
- 1.44.2
- Visual Studio Code
工程
- Google Chrome Extensionsの各ファイルを置くフォルダーを作成する
- manifest.jsonを作成し、必要事項を記入する
- Hello Extensions!と表示するhtmlファイルを作成する
- アイコン用のpngファイルを用意する
- Google Chromeで
chrome://extensions/
にアクセス デベロッパー モード
をONにするパッケージ化されていない拡張機能を読み込む
ボタンを押し、工程1で作成したプロジェクトフォルダーを指定する- 追加したGoogle Chrome Extensionsを試す
- ※ところどころの工程は省略する
工程2 manifest.jsonを作成し、必要事項を記入する
{ "manifest_version" : 2, "name" : "Hello Extension", "description" : "Base Level Extension", "version" : "0.1.0.0", "browser_action" : { "default_popup" : "hello.html", "default_icon" : "comment128.png" }, "commands" : { "_execute_browser_action" : { "suggested_key" : { "default" : "Ctrl+Shift+F", "mac": "MacCtrl+Shift+F" }, "description" : "Open hello.html" } } }
browser_action
のdefault_popup
に後工程で作成するhtmlファイルの名称を記入browser_action
のdefault_icon
に後工程で追加するpngファイルの名称を記入commands
は省略しても良い- キー入力でGoogle Chrome Extensionsを起動させたいなら追加しておく
工程3 Hello Extensions!と表示するhtmlファイルを作成する
<html> <body> <h1>Hello Extensions!</h1> </body> </html>
- ほぼお手本のまま
工程4 アイコン用のpngファイルを用意する
- ICOOON MONOさんなどからお好きな画像をどうぞ
工程6 デベロッパー モード
をONにする
- 画面右上にドグルスイッチがあるのでONにする
工程8 追加したGoogle Chrome Extensionsを試す
- Google Chrome Extensionsは追加するとアドレスバーの右側に表示される
- 設定したアイコン用のpngファイルがボタンに表示される
所感
意外と簡単に出来た。
業務でちょっとあったら便利だなーと思うものを作ってみたい。
Vue.js, computedは1または2回実行するのか?
はじめに
TLを眺めていたら次の書き込みがあった。
https://twitter.com/mpyw/status/1251517636984352768
ここのところVue.jsを触れていなかったので復習のつもりで確認した。
動作環境
- Web Browser
- Google Chrome
- 81.0.4044.113(Official Build)(64bit)
- Google Chrome
開発環境
- Editor
- Visual Studio Code
- 1.44.1
- Visual Studio Code
- Vue.js
- Version 2.6.11
console.log(Vue.version);
で確認した
- Version 2.6.11
結論
結論から書くとcomputedは1回実行した。
ソースコード全文
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hello, computed!</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <div>{{ foo }}</div> <div>{{ bar }}</div> <div>{{ fooAndBar }}</div> <div> <button v-on:click="Test">押してね!</button> </div> </div> <script> console.log(Vue.version); var app = new Vue({ el: '#app', data: { foo : 1, bar : 1 }, computed : { fooAndBar : function() { console.log("computed"); return this.foo + this.bar; } }, methods : { Test : function() { this.foo = 2; // fooAndBarで利用しているプロパティを変更 this.bar = 3; // 〃 } }, watch : { foo : function(newValue, oldValue) { console.log(`new : ${newValue}, old : ${oldValue}`) }, bar : function(newValue, oldValue) { console.log(`new : ${newValue}, old : ${oldValue}`) } } }); </script> </body> </html>
所感
v-on:click
やmethods
の存在を忘れていた・・・。
編集していて思い出した。watch
はおまけ。
触れていないと忘れてしまう。
JavaScript, Notification APIを使ってトースト通知をする、その2
はじめに
前回のNotificationのインスタンスを作成した後のオブジェクトはどうするんだ?と気になったので調べた。
動作環境
- Web Browser
- Google Chrome
- 81.0.4044.113(Official Build)(64bit)
- Google Chrome
開発環境
- Editor
- Visual Studio Code
- 1.44.2
- Visual Studio Code
イベントを設定できる
const title = "Good day!"; const options = { body : "It's a wonderful day!?", icon : "../Image/Icon/onsen64.png" }; const notification = new Notification(title, options); notification.onclick = function(event) { console.log("クリックしましたね!"); }; notification.onshow = function(event) { console.log("表示しましたね!"); }; notification.onclose = function(event) { console.log("閉じましたね!"); }; notification.onerror = function(event) { console.log("エラーです!"); };
onerror
は動作未確認。
onclick
内でthrow "sample"
を実行したけど発火しなかった。
おまけ、クリックイベント時のtimestampを得る
notification.onclick = function(event) { console.log(new Date(this.timestamp)); };
最初はoptions
のdata
プロパティにnew Date()
を仕込んでいたけど、
console.log(this);
の表示を見ていたらtimestamp
プロパティの存在に気づいた。
一部のブラウザでは未対応なので注意が必要か。
おまけ、雑記
dir
プロパティは指定してみたが変化なしsilent
プロパティはtrue
にしたら通知音が消えた
参考
JavaScript, Notification APIを使ってトースト通知をする
はじめに
トースト通知(バナー通知)を使ってみたい。
C#でやってみたいが、少し調べてみたら面倒そうな印象を受けた(やるならUWPか・・・)。
他に試せるとしたらC#以外に触れている言語だとJavaScriptだ。
初めてのJavaScriptで少しトースト通知に触れた記憶があったのであらためて調べて試した。
動作環境
- Web Browser
- Google Chrome
- 81.0.4044.113(Official Build)(64bit)
- Google Chrome
開発環境
- Editor
- Visual Studio Code
- 1.44.1
- Visual Studio Code
トースト通知を表示するには?
Notification
オブジェクトを利用する。
MDNを見れば良いと思うんだ。
Notification APIは使えるか?
if(window.Notification) { console.log("OK"); } else { console.log("NG"); }
通知の設定はどうなっているか?
const permission = Notification.permission; if(permission === "default") { console.log("通知未設定"); } else if(permission === "granted") { console.log("通知を許可した。"); } else if(permission === "denied") { console.log("通知を拒否した。"); }
まずは通知の設定を確認しdefault
やdenied
ならNotification.requestPermission
メソッドを使い、許可を得る。
許可を得ればgranted
になるので、あとはNotification
オブジェクトのインスタンスを作成すればトースト通知が使える。
通知の設定をするには?
Notification.requestPermission((result) => { if(permission === "default") { console.log("通知未設定"); } else if(permission === "granted") { console.log("通知を許可した。"); } else if(permission === "denied") { console.log("通知を拒否した。"); } });
「許可」ボタンを押すとgranted
となり、トースト通知が使える。
「ブロック」ボタンを押すとdenied
、「×」ボタンを押すとdefault
となりトースト通知は使えない。
↓設定ダイアログ
トースト通知を表示する1、タイトルのみ
const title = "Good day!"; const notification = new Notification(title);
↓こうなる
トースト通知を表示する2、本文(サブタイトルっぽい)を追加
const title = "Good day!"; const options = { body : "It's a wonderful day!?" }; const notification = new Notification(title, options);
↓こうなる
トースト通知を表示する3、アイコンを追加
const title = "Good day!"; const options = { body : "It's a wonderful day!?", icon : "../Image/Icon/onsen.png" }; const notification = new Notification(title, options);
↓こうなる
iconは.jpg
も表示できた。.svg
は表示できなかった。
一応・・・options
は他にもプロパティがある。
※画像はICOOON-MONOさんにあるものを利用した。素敵な画像をありがとうございます!
おまけ1、iconに使う画像は最低でも64pxが良さそう
トースト通知を表示する3、アイコンを追加
では32pxを利用したが若干ぼけている。
↓こちらは64px版。見比べてほしい。
おまけ2、半角文字だと1行は何文字分か?
34文字
だった。
うっ、アイコンを設定したら30文字
だった。
※bodyも同じ文字数だった。
おまけ3、全角文字だと1行は何文字分か?
18文字
だった。
うぅ、アイコンを設定したら16文字
だった。
※bodyも同じ文字数だった。
おまけ4、アイコンは何pxから大きくなるのか?
1px
から大きくなる..png
だからだろうか。
.ico
なら違う結果かもしれない。
所感
JavaScriptなら簡単にトースト通知が扱えることが分かった。
IEとSafariでは対応していないので注意が必要か。
参考になりました!
C#, LINQのSumで複数のTimeSpanの合計を得る
はじめに
↓こんな感じでできると思っていた。
// LINQを使う using System.Linq; // 集計対象 var timespans = new[] { new TimeSpan(0, 0, 1), new TimeSpan(0, 1, 0), new TimeSpan(1, 0, 0), }; var total_time = timespans.Sum();
「TimeSpan[]には引数無しのSumの定義は無いですよ」(意訳)とVisual Studioさんが告げる。
こうします
var total_ticks = timespans.Sum(t => t.Ticks); var total_time = new TimeSpan(total_ticks); // 01:01:01
おまけ?分単位や秒単位だといくつになるか?
var total_minutes = total_time.TotalMinutes; // 61.016666666666666 var total_seconds = total_time.TotalSeconds; // 3661
他にもTotalHours
やTotalDays
、TotalMilliseconds
がある。便利だ。
おまけ?TimeSpanのインスタンス作成時の引数ticksに最大値を入れると・・・?
var max_timespan = new TimeSpan(long.MaxValue);
10675199.02:48:05.4775807
になった。
ちなみにlong.MaxValue
は9223372036854775807
。
10675199
は約29247
年、遠大だ。
オーバーフローするとマイナスに転じるので注意しよう(発生しそうにない)。
雑記
小さく分けて書いてみた。こっちの方が良さげ。
補足
IDE
- Microsoft Visual Studio Community 2019
- Version 16.5.3
- Microsoft .NET Framework
- Version 4.8.03752
プロジェクト
- コンソール アプリ(C#)
- .NET Core 3.1
C#, LINQのGroupByで重複した要素と重複した要素が何個あるかを得る
はじめに
集計対象が複数のプロパティを持つオブジェクトの重複した要素と重複した要素が何個あるかが欲しくなった1。
集計対象が1オブジェクト2の配列やコレクションだったらDistinct
からのCount
で済む。
ソースコード全文
using System; using System.Linq; namespace Sample { class Program { static void Main(string[] args) { // 集計対象 var Points = new[] { new { X = 0, Y = 0 }, new { X = 0, Y = 1 }, new { X = 0, Y = 1 }, new { X = 1, Y = 0 }, new { X = 1, Y = 0 }, new { X = 1, Y = 0 }, new { X = 1, Y = 1 }, new { X = 1, Y = 1 }, new { X = 1, Y = 1 }, new { X = 1, Y = 1 }, }; // Method syntax // 1プロパティをグループ化 var pointXs = Points.GroupBy(point => point.X); /* ↓表示結果 0 1 */ foreach(var pointX in pointXs) { Console.WriteLine(pointX.Key); } // 2プロパティをグループ化、おまけで重複したグループ数を得る var points = Points.GroupBy(point => new { point.X, point.Y }) .Select(point => new { point.Key.X, point.Key.Y, Count = point.Count() }); /* ↓表示結果 { X = 0, Y = 0, Count = 1 } { X = 0, Y = 1, Count = 2 } { X = 1, Y = 0, Count = 3 } { X = 1, Y = 1, Count = 4 } */ foreach(var point in points) { Console.WriteLine(point); } #if false // Query syntax var result = from pointXs in Points group pointXs by pointXs.X; foreach(var item in result) { Console.WriteLine(item.Key); } var points = from pointXYs in Points group pointXYs by new { pointXYs.X, pointXYs.Y } into point select new { point.Key.X, point.Key.Y, Count = point.Count() }; foreach(var point in points) { Console.WriteLine(point); } #endif } } }
所感
個人的にはメソッド構文の方がクエリー構文より使いやすい。
メソッド構文はクエリー構文より命名するオブジェクトの数が少なくて済むから。
※クエリー構文はSQLっぽく書けるから好きではあるが。
※何気にクエリー構文は行頭が揃うのが良い。上記のソースコードだとfrom
とgroup
とselect
の開始位置。
補足
IDE
- Microsoft Visual Studio Community 2019
- Version 16.5.3
- Microsoft .NET Framework
- Version 4.8.03752
プロジェクト
- コンソール アプリ(C#)
- .NET Core 3.1
書いた経緯など
SQLならパッと思いつくんだけどLINQは慣れていないので書き方が分からなかった。
また、調べるのも面倒なので備忘録として書き残した。
ついでにクエリー構文も調べて書いたけど、今後はメソッド構文だけを書くか。
載せるソースコードが長くなってしまう。