JavaScript 簡易データベースもどきに(?)検索機能を付加してみた
<!DOCTYPE html> <title>?</title> <meta charset="utf-8"> <style> li label { color: green; font-weight: bold; padding-right: 1ex;} </style> <body> <div> <label>KeyWord:</label> <input type="search" autofocus> <em>space で区切ることも可能</em> <ul id="list"></ul> </div> <script> { //_____________________________________________________ /* 関数を遅らせて実行する let func = new DelayWork ((s)=>{alert(s)}, 1000); func.start ('Start!!'); //実行 func.stop (); //中止 */ class DelayWork { constructor (callBackFunc, wait = 500) { this.callBackFunc = callBackFunc; // func.bind (this) this.wait = wait; this.timerID = null; } start (...arg) { if (! this.timerID) { let cbfunc = () => { this.timerID = null; this.callBackFunc (...arg); }; this.timerID = setTimeout (cbfunc, this.wait); } return this; } stop () { if (this.timerID) clearTimeout (this.timerID); this.timerID = null; return this; } } //_____________________________________________________ class DelayHandler { constructor (handler, wait = 300) { let cbFunc; switch (Object.prototype.toString.call (handler)) { case '[object Object]' : if ('handleEvent' in handler) if ('function' === typeof handler.handleEvent) cbFunc = handler.handleEvent.bind (handler); break; case '[object Function]' : cbFunc = handler; break; default: throw new Error ('Not handleEvent'); break; } this.handler = new DelayWork (cbFunc, this.wait); this.wait = wait; } handleEvent (event) { this.handler.stop ().start (event); } } //_____________________________________________________ //記事 const Article_DEF_OPTION = { }; class Article { constructor (title = '', key = title, text = '', date = new Date, option = { }) { if (1 > title.length) arguments.length; this.title = title; this.text = text; this.key = key; this.date = date; this.option = Object.assign ({ }, Article_DEF_OPTION, option); } } //_____________________________________________________ const Book_DEF_OPTION = { }; //記事を本にまとめる。keyをもとに検索機能がある class Book { constructor (book = [ ], option = { }) { this.book = book; this.option = Object.assign ({ }, Book_DEF_OPTION, option); } append (...args) { this.book.push (new Article (...args)); return this; } load (ary) { ary.forEach (args => this.append (...args)); return this; } } //_____________________________________________________ //Book に検索機能を追加する const ExBook_DEF_OPTION = { }, REG_NORMALIZATION = /[-\/\\^$*+?.()|\[\]{}]/g, //正規化 REG_SPLITER = /\s+/g,//空白で区切る REG_TRIM = /(^\s+|\s+$|\s+(?=\s))/g,//前後の空白と中間の2文字以上の空白にマッチ REG_KEY = (str) => {//検索文字から正規表現を作る //x(?=y0)(?=y1)(?=yn)... let [a, ...bc] = str.replace(REG_NORMALIZATION, '\\$&').split (REG_SPLITER); return new RegExp (a + bc.map (s => `(?=.*${s})`).join (''), 'i'); }; class ExBook extends Book { constructor (book = [ ], display, option = { }) { super (book, Object.assign ({ }, ExBook_DEF_OPTION, option)); this.display = display; this.found = [ ]; //検索対象 this.key = ''; } find (arg = '') { let key = arg.replace (REG_TRIM, ''), len = key.length; if (len) { let cnt = this.key.length; if (! cnt || len < cnt) this.found = this.book.slice ();//検索対象を初期化 copy if (key !== this.key) { let reg = REG_KEY (key); this.found = this.found.filter (rec => reg.test (rec.key)); this.key = key; this.display.write (this.found.slice()); } } else { this.display.cls (); this.key = ''; } return this; } handleEvent (event) { this.find (event.target.value); } } //_____________________________________________________ const Display_DEF_OPTION = { disp_row : 1, //一回の処理で表示する行 disp_wait : 30, //次の表示処理までの時間 disp_max : 30 //最大の表示する行 }, createElement = function (n) { return this.createElement (n) }, createRow = (function (doc) { let [li, label, span] = ['li', 'label', 'span'].map (createElement, doc) li.appendChild (label); li.appendChild (span); return function (title, text) { label.textContent = title; span.textContent = text; return li.cloneNode (true); }; })(document); class Display { constructor (target, option = { }) { option = Object.assign ({ }, Display_DEF_OPTION, option) this.target = target; this.option = option; this.loop = new DelayWork (this.outByBit.bind (this), option.disp_wait); } write (rows = [ ]) { this.cls (); this.outByBit (rows.splice (0, this.option.disp_max)); return this; } outByBit (rows) { let fgm = this.target.ownerDocument.createDocumentFragment (), part = rows.splice (0, this.option.disp_row); this.target.appendChild (part.reduce ((a,b)=>{ a.appendChild (createRow (b.title + ":", b.text)); return a; }, fgm)); if (rows.length) this.loop.start (rows); return this; } cls () { this.loop.stop (); for (let p = this.target, e; e = p.firstChild; ) e.remove (); return this; } } //_____________________________________________________ this.Article = Article; this.Book = ExBook; this.Display = Display; this.DelayHandler = DelayHandler; } //_____________________________________________________ const //[タイトル... | 検索キー] テキスト(次のタイトル区切りの"["の直前までが対象となる notes = ` [ Array.prototype.push | array push ] 配列の最後に要素を追加する [ Array.prototype.pop | array pop ] 配列の最後から要素を削除し、その要素を返す [Array.prototype.map | array map] 配列から生成した配列を返す [ array.prototype.slice | array slice ] 配列から指定した要素を削除する `; let reg, ary, words = [ ]; { let text = '(.+?)'; let spc = '\\s*'; let text2 = '([\\s\\S]+?)'; let title = '\\['+ spc + text + '(?:' + spc + '\\|' + spc + text + ')?'+ spc + '\\]'; let note = spc + text2 + '(?=\\s*\\[|\\s*$)'; reg = new RegExp (title + note , 'gi'); } while (ary = reg.exec (notes)) { let [, ...arg] = ary; console.log(arg); words.push (new Article (...arg)); } let dic = new Book (words, new Display (document.getElementById ('list'))); document.querySelector ('input[type="search"]') .addEventListener ('input', new DelayHandler (dic), false); </script>
Javascript イベントを遅らせて発火させる
Javascript イベントを遅らせて発火させる
class DelayWork { constructor (callBackFunc, wait = 500) { this.callBackFunc = callBackFunc; // func.bind (this) this.wait = wait; this.timerID = null; } start (...arg) { if (! this.timerID) { let cbfunc = () => { this.timerID = null; this.callBackFunc (...arg); }; this.timerID = setTimeout (cbfunc, this.wait); } return this; } stop () { if (this.timerID) clearTimeout (this.timerID); this.timerID = null; return this; } } //_____________________________________________________ class DelayHandler { constructor (handler, wait = 300) { let cbFunc; switch (Object.prototype.toString.call (handler)) { case '[object Object]' : if ('handleEvent' in handler) if ('function' === typeof handler.handleEvent) cbFunc = handler.handleEvent.bind (handler); break; case '[object Function]' : cbFunc = handler; break; default: throw new Error ('Not handleEvent'); break; } this.handler = new DelayWork (cbFunc, this.wait); this.wait = wait; } handleEvent (event) { this.handler.stop ().start (event); } } //_____________________________________________________ function handler (event) { ; } document.querySelector ('input[type="search"]') .addEventListener ('input', new DelayHandler (handler), false);
時間間隔をちょっと考えて
時間間隔をちょっと考えて
class DateInterval { constructor (begin, end) { this.begin = begin; this.end = end; } isInRange (date = new Date) { let b = +this.begin, e = +this.end, d = +date; return b <= d ? d <= e: false; } copy () { return new DateInterval (new Date (this.begin), new Date (this.end)); } static range (...arg) { let [s, m, h, d] = [...arg.reverse (), 0, 0, 0, 0]; if (31 < d) throw new Error; return new Date (Date.UTC (1970, 0, d + 1, h, m, s, (s % 1 * 1000))); } static split (dateInterval, date) { let rst = [ ], max = +dateInterval.end, step = +date; for (let i = new Date (dateInterval.begin); i < max; i.setTime (+i +step)) rst.push (new Date (i)); return rst; } static create (a, b) { return new DateInterval (new Date (...a), new Date (...b)); } } let a = DateInterval.range (1,0,0); let b = DateInterval.create ([1,0,1], [1,0,2]); console.log (DateInterval.split (b, a));
まだ移譲が不足なのだろうか?
まだ移譲が不足なのだろうか?
<!DOCTYPE html> <title>?</title> <meta charset="utf-8"> <style> label { color: green; margin: 1ex 1ex 1ex; font-weight: bold;} </style> <body> <div> <label>KeyWord:</label> <input type="search" id="keyword" autofocus> <em>space で区切ることも可能</em> <ul id="list"></ul> </div> <script> { class DelayWork { constructor (callBackFunc, wait = 1000) { this.callBackFunc = callBackFunc; // func.bind (this) this.wait = wait; this.timerID = null; } start (...arg) { if (! this.timerID) { let cbfunc = () => { this.timerID = null; this.callBackFunc (...arg); }; this.timerID = setTimeout (cbfunc, this.wait); } return this; } stop () { if (this.timerID) clearTimeout (this.timerID); this.timerID = null; return this; } } //記事 const Article_DEF_OPTION = { }; class Article { constructor (title = '', text = '', date = new Date, keyword = title, option = { }) { if (1 > title.length) arguments.length; this.title = title; this.text = text; this.key = keyword; this.date = date; this.option = Object.assign ({ }, Article_DEF_OPTION, option); } } //_____________________________________________________ const Book_DEF_OPTION = { }, Book_REG_NORMALIZATION = /[-\/\\^$*+?.()|\[\]{}]/g, book_REG_SPLITER = /\s+/g, Book_createRegkey = (str) => { let [a, ...bc] = str.replace(Book_REG_NORMALIZATION, '\\$&').split (book_REG_SPLITER); return new RegExp (a + bc.map (s => `(?=.*${s})`), 'i'); //x(?=y0)(?=y1)(?=yn)... }; //記事を本にまとめる。keyをもとに検索機能がある class Book { constructor (book = [ ], option = { }) { this.book = book; this.option = Object.assign ({ }, Book_DEF_OPTION, option); this.current = [ ]; //検索された記事 this.key = ''; //検索ワードの記憶 } append (...args) { this.book.push (new Article (...args)); return this; } load (ary) { ary.forEach (args => this.append (...args)); return this; } search (key = '') { key = key.trim (); let len = key.length; if (len) { if (0 === this.key.length || len < this.key.length) this.current = this.book.slice (); if (key !== this.key) { let reg = Book_createRegkey (key); this.current = this.current.filter (rec => reg.test (rec.key)); this.key = key; } } else { this.current = [ ]; this.key = ''; } return this; } } //_____________________________________________________ //Book に表示機能を追加する const ExBook_DEF_OPTION = { disp_row : 3, //一回の処理で表示する行 disp_wait : 300, //次の表示処理までの時間 disp_max : 30 //最大の表示する行 }; class ExBook extends Book { constructor (book = [ ], output, option = { }) { option = Object.assign ({ }, ExBook_DEF_OPTION, option); super (book, option); this.output = output; this.loop = new DelayWork (this.outByBit.bind (this), option.disp_wait); } display (rows = this.current.slice ()) { this.cls (); this.outByBit (rows.splice (0, this.option.disp_max)); return this; } cls () { this.loop.stop (); this.output.cls (); return this; } outByBit (rows = [ ]) { this.output.out (rows.splice (0, this.option.disp_row)); if (rows.length) this.loop.start (rows); return this; } } //_____________________________________________________ //Book に入力機能を追加する const Ex2Book_DEF_OPTION = { inkey_wait: 1000 } class Ex2Book extends ExBook { constructor (book, input, output, option = { }) { option = Object.assign ({ }, Ex2Book_DEF_OPTION, option); super (book, output, option); this.input = input; this.routine = new DelayWork (this.find.bind (this), option.inkey_wait); input.addEventListener ('input', this, false); } find (key = '') { key = key.trim (); if (key !== this.key) this.search (key).display (); return this; } handleEvent (event) { this.routine.stop ().start (event.target.value); return this; } } //_____________________________________________________ class ListViewer { constructor (target) { this.target = target; } cls () { for (let p = this.target, e; e = p.firstChild; e.remove ()); return this; } out (rows = [ ]) { let doc = this.target.ownerDocument, li = doc.createElement ('li'), label = doc.createElement ('label'), span = doc.createElement ('span'), fgm = doc.createDocumentFragment (); li.appendChild (label); li.appendChild (span); this.target.appendChild (rows.reduce ((a, {title, text}) => { label.textContent = title; span.textContent = text; fgm.appendChild (li.cloneNode (true)); return a; }, fgm)); return this; } } //_____________________________________________________ this.Book = Ex2Book; this.ListViewer = ListViewer; } //_____________________________________________________ const article = [ { key: 'array map', title: 'Array.map', text: '配列から新たに作成した配列を返す'}, { key: 'array filter', title: 'Array.filter', text: '配列から条件を満たす配列を返す'}, { key: 'array some', title: 'Array.some', text: '配列から条件を一つでも満たすと true を返す'}, { key: 'array reduce', title: 'Array.reduce', text: '配列評価しながら配列を返す'} ], DIC2 = ` Array.prototype.push 配列の末尾に要素を追加する array push Array.prototype.pop 配列の末尾の要素を削除する array pop Array.prototype.shift 配列の先頭の要素を削除する array shift Array.prototype.unshift 配列の先頭に要素を追加する array unshift Array.prototype.indexOf 要素のインデックスを取得する array indexOf Array.prototype.splice インデックス位置を指定して要素を削除する array splice Array.prototype.slice 配列のコピー array slice `; let inp = document.querySelector ('#keyword'), out = new ListViewer (document.querySelector ('#list')), dic = new Book (article, inp, out); dic.load ( DIC2 .trim () .split (/\r|\n|\r|\n/) .map (s => s.trim().split (/\t|\s{2,}/g) .map (s => s.trim ()) ) ); </script>
teratail に登録する
それにしても色々な質問があるものだ。
すべてには答えきれないね。
そこでふと考えた。
解説などしないで、男ならコードだけで勝負しようと思った。
解説などいっさしない!
それに無視することも私の自由だ。
これからは、そうしよう。
タグ別ランキング1位の人の喰い入り様は、尋常ではない。
--
人様の書いたコードは、容易く理解できるものではない。
理解しようともせず、丸投げしてきた。
これも無視しよう。
使われた言葉に数値をつけてみる
https://oshiete.goo.ne.jp/qa/10921080.html
使われた言葉に点数を加算していくのだが、最大値を超えないようにするには?
そんで、考えた。
あっ!光の速度はこえられない!
相対論的な速度の加算方式を利用しよっと。
<!DOCTYPE html> <meta charset="UTF-8"> <html lang="ja"> <title>?</title> <style> </style> <body> <h1>Test</h1> <input type="search" value="リンゴ" onblur="dic(this.value)"><br> <textarea cols="80" rows="10"></textarea> <body> <script> class R { constructor (key, level) { this.key = [ ].concat (key); this.level = level; } add (key, level) { this.key.push (key); let l0 = this.level, l1 = level; this.level = (l0 + l1) / (1 + l0 * l1); return this; } sort () { this.key.sort ((a, b) => HASH[a].level < HASH[b].level); } } let words = [ ['苺', '赤い', 'おいしい', 'すっぱい'], ['リンゴ', '青森', '赤い', 'おいしい', 'すっぱい', 'シャイニーアップルジュース'] ]; let HASH = { }; for (let ws of words) { let key = ws.shift (); let gain = 1 / ws.length; let c = 1; HASH[key] = new R (ws, c); for (let w of ws) { c *= gain; if (w in HASH) { HASH[w].add (key, c); } else { HASH[w] = new R (key, c); } } } function dic (key) { let mess = '知らない'; if (key in HASH) { let obj = HASH[key]; obj.sort (); mess = obj.key.map (s => s + '(' +HASH[s].level+ ')').join ('\n'); } document.querySelector ('textarea').value = mess; } </script>
ANYCUBIC i3 Mega 3Dプリンタを使いこなす
まともに記事を書き上げたことがないが、ちょいちょい写真もアップしながら書こうと思う
2018年、4台のマシンを購入する
トラブルの解決法をまとめておく
ネジは必ず締めましする
4台購入したが、どれもどこかしら緩んでいた。なので手当たり次第ネジを締める。
長く使用できるように改造する
スッテッピングモーターが5個使用されている。モータはトルクもあるし発熱もする。
なのでヒートシンクを全てに取り付ける
https://www.amazon.co.jp/gp/product/B07HFQWZM8/ref=oh_aui_search_detailpage?ie=UTF8&th=1
裏面を外し、内部にある下部のモーターにもヒートシンクを貼る(3ヶ使用)
ヘッドを支えるフレームの中に隠れているモーターが2個、それぞれにヒートシンクを貼る
ヒートベットが暖まりやすいように、その裏に断熱材を貼る
https://www.amazon.co.jp/gp/product/B0793NVCL4/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1
`
印刷中にフィラメントを溶かすヘッドの温度が安定しない
温度センサーを固定するネジが緩んでいる
温度センサーのヘッド側の出張った配線が断熱してしまう
これは交換しかない