alert(hashTest[key]);これは当然のようにアラートで出てくる値は"12345"だけです。JavaScriptのオブジェクトはキーが文字列限定のDictionary(C#脳ですみません)で、キーに文字列以外のものを突っ込んだ場合、自動的に文字列に変換される。Object]"になるから上書きされる、というお話。結果は1です、ごめんなさいとなっていました。ちなみに、何故かFirefoxでは10になります。IEやChromeは1なんですけどね。linq.jsの内部の動きから考えるに、Firefoxのほうが変な挙動なのは確かなのですが良くわかりません。ブラウザ間で互換の取れてない動きが出てしまう、というのもまた良くない話です。そんなわけで直しました。めでたしめでたし、のようでいて複雑な気分。いうのも内部コードの実行効率が酷いことになってしまったからです。false;}最初にPrimitive、つまり数字や文字列であるかを判断し、プリミティブであればhasOwnPropertyでキーがあるかないかを判断。そのままではキーとして使えないオブジェクトに対しては、線形探索で全部舐めて探してるんですね―。うはー、大量の配列に使った場合の遅さが怖すぎる。Hashtableなんかも同じような内容なので、しょうがないみたいです、素のJavaScriptでは。ハッシュコードを算出するために重たい計算を挟めば、それはそれで本末転倒ですし。EqualityComparerJavaScriptのObjectは参照型、なので全ての値が同一であろうとも、別のオブジェクトであるのなら別だと判断される。それでは実用性に乏しい。1{test:"dummy"}を10個生成し、それを重複除去するとしたら、望む値は当然、1。いった動作が出来るようにDistinctなどの集合演算系にキー指定が出来るようになりました。いえばC#の匿名型はクラスなのに重複除去されるのは何でだろう、と思ったらちゃんと「すべてのプロパティが等しい場合のみ、等しい」ように作られているようです。ユーザーがどういう動作を望んでいるのか分かってる。UnionにcompareSelectorを追加、という形になります。比較関数にするかキーセレクターにするかで悩んだのですが、比較関数だと使用時の定義が面倒くさいので、実用性を考えて簡易的なもののほうが良いかな、と思いキーセレクターにしました。9割以上は同じものの比較ですよねー、という決めつけです。複数の値で比較したい時は適当に連結する、しかないです。塩でも振りながら文字列にして結合してください。お手軽でそこそこ確実な手を言えば、ToJSONメソッドを使ってJSONに変換するのも手です。4true:false,true:true,false:true,false:falseの4通りのどれかが10個なので、重複除去すると合計数は4つ。ところでそうそう、集合演算で線形探索とかフザけるなタコ、と思った場合はこのようにJSON化することで(値参照になりますが)回避できます。何かバッドノウハウみたいで素敵。そもそもオブジェクトにたいしてキー指定無しの集合演算自体が使う機会なんてほとんどないとは思いますが。0.0.0.1を同梱しました。更新系はほとんど未実装ですが、抽出系のメソッドで主要なものは動いているので、お試しぐらいには使えると思います。面倒くさい面倒くさい、と思ってしまうわけなので素の状態と比べたらとっても役立ちです。サンプルとしてTwitterビューアを同梱しました。AttachEventをつけた結果、限りなくAjaxライブラリな状態になってしまいました。この辺はオマケみたいなもので、基本的には抽出->加工がメイン、なはずです。あとドメイン間の通信は当然出来ないので、IEの場合はインターネットオプション→セキリティ→レベルカスタマイズ→ドメイン間データソースアクセスを有効にしてください。Firefoxでのやり方は分かりません。ただのデモで実用的なものでもないので、IEで見ていただければと思います。サンプルなので、チュートリアルがわりに解説します。</div></body>X.Initializeはwindow.onloadに対するイベント登録です。Xmlとは全く関係ないメソッドは入れたくなかったのですが、やむをえず。最初はX.Body()でdocument.bodyが取れるので、それにたいしてAttachEventでいいかなーと思ったのですが、ヘッダ内だとbodyがまだ生成されていないのでイベント登録できなくて、特例的にこのメソッドを作りました。登録するものはボタンを押した時に発生するイベントの登録用関数。descriptionから辿っていますが、IDが振ってあればX.ID()でダイレクトに取れます。思考の流れ通りの、非常にシンプルで分かりやすい登録方法だと思います。XMLを読み込んでいるX.Loadですが、これは第一引数がファイルパス、第二引数がコールバック関数になります。第二引数を省略した場合は同期通信になります。X.Load("hoge.xml")という使い方が出来るわけです。ローカル環境でテストしたい場合は同期通信のほうを使った方がやりやすいかと思います。Descendantsは子孫ノードの取得。XMLの要素取得では最も使われるものだと思いますが、ぶっちゃけgetElementsByTagNameです。その次のSelectは射影です、ようするにmapです。Xmlのキモの部分で、XMLをオブジェクトに変換します。xEleには"status"以下の要素が順番に渡されていくので、それに対してElement("要素名")の値(Value)を取得。Value()には変換関数を渡すことが出来るので、stringじゃなくintにしておきたい、という場合にはparseIntなんかを入れると良いです。ForEachは、Selectを通って出来たobjectに対してforeachです。今回はpタグのエレメントをつくって挿入してplaceHolderに追加-。Xmlではもっと洗練された形になっているので修正するつもりです。今は暫定ということで、この形での登録しか出来ません。あとCreateHTMLElementということで、HTMLとXMLを区別しているのも頂けないですね......。ここは統一したやり方で何とかなるよう調整したいと思います。FAQわざわざjQueryじゃないこんな意味不明粗製ライブラリの使い方を覚える必要あるの?それ言ったらXPathイラネ、とかE4Xイラネ、とかにも繋がりますし。そんなに比較するようなものじゃないと思います。出来ることの幅も全然違いますし。こちらはリスト/DOM操作のみです。リスト/DOM操作でのみ言えばこちらのほうが多くのことがスムーズに出来ると思います。Linqの学習ができること、です。中身はともかく表面的な模写としてはわりと忠実なので、C#でも同じ書き方で十分行けます。Disって欲しいんだって、ほんとうに。0反響よりは100のDis。そもそもlinq.jsって何?初回リリース時のチュートリアルをどうぞ。Xmlのメソッド群はXPathにそれぞれ対応する。XPathを覚えることなく、メソッドを繋げていくことで対象ノードが絞りこめる。これによる利点は、IntelliSenseが効くので高速にタイプセーフに思考の流れのまま記述出来るということ。簡潔とは程遠い勢いです。WhereでのAttributeの参照をもう少し綺麗に書ければ......。nullが敵すぎて困る。そんな時のため、というわけではないのでしょうがSystem.Xml.XPath名前空間をインポートすることで、XElementにXPathSelectElementsという拡張メソッドが追加されます。これで、root.XPathSelectElements("//h1[@class='hoge']/..");と、簡潔明快に記述できる。そりゃXPathのほうが簡潔になるのは「当たり前」ですもの。この程度ならまだいいけど、複雑怪奇になったときは(正規表現と同じように)解読出来ねえよ、と。個人的には全然LINQのほうが好きですよ!nullに気を遣う必要がなくなれば。いうか、XPath->IEnumerableは別に普通にLinqですけど。何かもうDescendants使う機会が無くなってしまう気がするなあ。linq.jsではXPathの実装までやるつもりはありません。あー、解析してLinq形式に変換する程度ならやるかも。いって、愚直にイテレータ回してるので速度でいったら明らかに遅いんですけどね。翌々冷静に考えるとネタというか色物としかいえない仕上がりな気がしてきましたよ。みんなJavaScript-XPath使えばいいさ......。いえば、XAttributeのValueは代入可能で、当然代入すると即座に反映されるわけなんだけど、JavaScriptだとメソッドが擬態したプロパティって無理ですよね?Value()とSetValue()に分けるしかないのかなあ。XElementがその形なので違和感無いといえば無いんですけど微妙(そもそもXElementのほうもValueプロパティ一個でいいのに、何で分けたんだろう)。誰か良い案あればください。今日のlinq.js誰得状態になってもちゃんと書き進めてますので安心。あ、linq.jsダウンロード50到達ありがとうございます。Xml搭載で100ダウンロード到達を目指します。ええ、と、子ノードを全部削除するよくあるメソッドを作ろうと思ったのです。XElementにも当然あります、「RemoveNodes」です。});thisはXElementで、Removeは自身を親ノードから削除するというもの。Elements()は子ノードを列挙するものなので、そのままForEachで削除していけば出来あがり。ないというよくある話を普通にやりました。列挙しているものの長さ(childNodes.length)がRemoveで変わっていってしまうんですね。});ToArray()でコピーを作って列挙。これなら問題なく動く。コピーのロスがあるので逆順forとかwhile(firstChild)使えよって話ではありますけど、今更速度どうこう言ってもしょうがないので普通に無視。言いつつ、書き直しましたけど。});やっぱ、Arrayを直接拡張してeachが使えるとスッキリしていいですねえ。うーん、E.From(E.From(要素).ToArray())のショートカットメソッドが欲しいかもしれない。Cloneというのも変だし......。CopyDoとかどうでしょう、ダサいですかダサいですね。いうか意味不明ですね。})},いやー、LINQは条件を好き勝手あとで継ぎ足していけるのがいいですよねー。再掲したのは前回のが間違っていたから。前回のElementsの例でpタグのものを取った時、TextNodeも取得しちゃってたのは完全に間違いです。TextNodeも含めたい時はNodes()メソッドを使い、Elements()ではNodeTypeがElementのものしか取れない。いうように直しました。Xmlの知識自体が欠けているので、Nodesメソッドを実装しようとしてから初めてこの事に気がついたという有様。Nodes()の戻り値はXNodeなんですね、XElementとXTextが混在するから......。いえば、要素名を大文字小文字を区別すべきか、しないほうがいいか悩み中。Xmlでは当然区別しているんですが、区別するとWhere使うときにタグの大文字小文字区別が面倒くさいとかあるので、区別なしにしちゃおうかなー、とは思ってます。Xmlの移植を始めました。JavaScript上で最も動かすことになるリストってDOMなので、欠かかせません←結論。これで大幅に使い道や表現の幅が広がりそうです。やり過ぎるとjQueryでいいぢゃん、的な捉えられかたをされてしまいそう。個人的には全然用途が違う、共存できるものだと思っているのだけど。Xml例と比べても、ほとんど書き方は一緒です。linq.jsではLinq.EnumerableのショートカットとしてEを使いましたので、今回はLinq.XElementのショートカットとしてXを使うことにしました。アルファベット一字系はちょっと危険かなあ、というところがあるので要再検討、でしょうか。値を得るValue()は、キャストのかわりにパースする関数を引数で取るようにしました。Value(parseInt)で数字が取れるわけです。カッコが一つ減って、少し見通しが良くなる。