質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
jqGrid

jqGridとは、jQqueryのプラグインであり、web上に表データの表示・操作を行う事が可能になります

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1858閲覧

連想配列の使い方、要素の参照方法が判らないので教えて下さい

hatsuzo

総合スコア56

jqGrid

jqGridとは、jQqueryのプラグインであり、web上に表データの表示・操作を行う事が可能になります

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/02/22 10:17

連想配列の使い方、要素の参照方法が良く判らないので教えて下さい。

jQueryのjqGridで作成されている配列オブジェクトの値をCSVに出力するスクリプトです。
先人のソースを参考にして見よう見まねで、何とか動くようになり、結果をExcelで開くことも出来るのですが、
いわゆる標準的なCSVの形式として、文字列をダブルクォーテーションで囲む、という形式にすることが出来ていません。
列の属性を判断するには、sorttypeというプロパティを持っているのでそれを参照して、文字か数字かを判断すればよいと思っています。

連想配列の並び順が確保できなかったので、列の順番を付けるためにkeyOrderという配列を設けています。
この配列に値の順に、colModelの中のsorttypeプロパティが'int'の場合には数値と見なすという判断ができればよいかと思うのですが、
どのように検索、参照すればよいのでしょうか?

もっと簡単な方法でできるというご意見もあろうことは承知しておりますが、当面の課題におきましてアドバイスをいただければ幸いです。

よろしくご指導ください。

Javascript

1var dt = [ 2 {cd:"A001", name:"鈴木", age:35} 3 ,{cd:"A002", name:"佐藤", age:45} 4 ,{cd:"A003", name:"田中", age:55} 5]; 6 7var keyOrder = [ 8 "cd", 9 "name", 10 "age" 11]; 12 13 14$("#list").jqGrid({ 15 data: dt 16 ,datatype: "local" 17 ,colNames:['CD', '名前', '年齢'] 18 ,colModel:[ 19 {index:'cd', name:'cd', width:'50px', align:'center'}, 20 {index:'name', name:'name', width:'100px', align:'left'}, 21 {index:'age', name:'age', width:'80px', align:'right', sorttype:'int'}, 22 ] 23 ,height: 150 24 ,multiselect: true 25 ,caption: '一覧' 26 ,rowNum: 5 27 ,rowList: [5, 10, 20] 28 ,viewrecords: true 29 ,pager: 'pg01' 30}); 31 32var ListToCSV = { 33 export: function() { 34 var csv_data = ""; 35 var j; 36 var line; 37 // 行データを取得する 38 var sel_list = $('#list').getGridParam('data'); 39 j = 0; 40 line = ""; 41 var header_list = $('#list').getGridParam('colNames'); 42 // 列属性の取得 --> ここから sorttypeプロパティを取り出したい 43 var col_list = $('#list').getGridParam('colModel'); 44 // 見出しの値を取得 45 header_list.forEach(function( key ) { 46 // chekbox列の除外 47 if ( key.indexOf('checkbox') == -1) { 48 if ( j != 0 ) line += ","; 49 line += key; 50 j ++; 51 } 52 }); 53 line += '\n'; 54 csv_data += line; 55 // 明細の値を取得 56 for (var i = 0; i < sel_list.length; i++) { 57 j = 0; 58 line = ""; 59 // 連想配列は並び順が保証されないので定義された順番(keyOrder)に書き出す 60 keyOrder.forEach(function( key ) { 61 62 // 63 // この部分で、keyの値に対応する列のsorttypeというプロパティを参照 64 // 65 // col_list[key]['sorttype'] では駄目でした。 66 67 if(sel_list[i][key]){ 68 var innerValue = sel_list[i][key]===null?'':sel_list[i][key].toString(); 69 } else { 70 var innerValue = ''; 71 } 72 // " を "" に置換 73 var result = innerValue.replace(/"/g, '""'); 74 // , 又は \n を含んでいる場合は ""で囲う 75 if (result.search(/("|,|\n)/g) >= 0) 76 result = '"' + result + '"'; 77 if ( j != 0 ) line += ","; 78 line += result; 79 j ++; 80 //} 81 }); 82 console.log(">" + line); 83 line += '\n'; 84 csv_data += line; 85 } 86 // 頭にbomコードを付けた 87 var csv_data_sjis = "\uFEFF" + csv_data; 88 return csv_data_sjis; 89 } 90}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2021/02/23 12:11

HTMLを含めた再現コードを書いてください。 もしくは、必要なデータをコピペ可能な形式で書いてください。 こちらで再現できなければ、正確な回答は出来ません。 > 列の属性を判断するには、sorttypeというプロパティを持っているのでそれを参照して、文字か数字かを判断すればよいと思っています。 この部分が理解できません。
hatsuzo

2021/02/24 00:07

think49さん コメントありがとうございました。 すみません。説明が足りませんでした。 $("#list").jqGrid({ data: dt ,datatype: "local" ,colNames:['CD', '名前', '年齢'] ,colModel:[ {index:'cd', name:'cd', width:'50px', align:'center'}, {index:'name', name:'name', width:'100px', align:'left'}, {index:'age', name:'age', width:'80px', align:'right', sorttype:'int'}, ] (以下略) } dataプロパティはデータの実体となる配列で、colModelプロパティで各列に対する属性が配列で定義されています。 その中の属性の一つとして、sorttypeがあり、その値がintであれば数値属性であることが識別できる ということです。 データの実体から見ると、 {cd:"A001", name:"鈴木", age:35} age列が数値属性であるという意味になります。 実際、フレームワーク(intra-mart)を使っているので、再現コードが書けないため、 $("#list").jqGrid({ の部分やデータの実体部分は実ソースには無いものですが、参照可能な データの形式で追記したものです。
think49

2021/02/24 03:38 編集

説明を努力しているのは伝わりましたが、まだ正確な状況がわかりません。 コピペで動作して、私が「期待するCSV文字列値」を返す関数に修正して頂ければ、修正可能と思います。 簡単にいえば、「入力値のサンプルコード」と「出力値のサンプル文字列」があれば、他は不要です。
guest

回答2

0

自己解決

お騒がせしました。
オブジェクトを持つ配列のインデックスを行、プロパティを列とみなした場合、
特定の列の値がキーワードに合致している行を探し、その行の別のプロパティを参照する、
つまりExcel関数でいうVlookupをする方法が判ればよいことに気づきました。
毎度colModelという配列にアクセスしているので不細工ですが、とりあえず動作しましたので、
ご連絡します。
アドバイスを頂きまして有難うございました。

Javascript

1$("#list").jqGrid({ 2 data: dt 3 ,datatype: "local" 4 ,colNames:['CD', '名前', '年齢'] 5 ,colModel:[ 6 {index:'cd', name:'cd', width:'50px', align:'center'}, 7 {index:'name', name:'name', width:'100px', align:'left'}, 8 {index:'age', name:'age', width:'80px', align:'right', sorttype:'int'}, 9 ] 10 ,height: 150 11 ,multiselect: true 12 ,caption: '一覧' 13 ,rowNum: 5 14 ,rowList: [5, 10, 20] 15 ,viewrecords: true 16 ,pager: 'pg01' 17}); 18 19var ListToCSV = { 20 export: function() { 21 var csv_data = ""; 22 var j; 23 var line; 24 // 行データを取得する 25 var sel_list = $('#list').getGridParam('data'); 26 j = 0; 27 line = ""; 28 var header_list = $('#list').getGridParam('colNames'); 29 var col_list = $('#list').getGridParam('colModel'); // ##### この行追加 30 for (var i = 0; i < sel_list.length; i++) { 31 j = 0; 32 line = ""; 33 keyOrder.forEach(function( key ) { 34 // ##### ここから追加 35 const col = col_list.find((p) => { 36 return (p.name === key); 37 }); 38 let intatr = false; 39 if (col.sorttype){ 40 if (col.sorttype === "int"){ 41 intatr = true; 42 } 43 } 44 // ##### ここまで追加 45 if(sel_list[i][key]){ 46 var innerValue = sel_list[i][key]===null?'':sel_list[i][key].toString(); 47 } else { 48 var innerValue = ''; 49 } 50 // " を "" に置換 51 var result = innerValue.replace(/"/g, '""'); 52 // , 又は \n を含んでいる場合は ""で囲う 53 //if (result.search(/("|,|\n)/g) >= 0) 54 if (result.search(/("|,|\n)/g) >= 0 || intatr == false) // ##### この行修正 55 result = '"' + result + '"'; 56 if ( j != 0 ) line += ","; 57 line += result; 58 j ++; 59 }); 60 console.log(">" + line); 61 line += '\n'; 62 csv_data += line; 63 } 64 // 頭にbomコードを付けた 65 var csv_data_sjis = "\uFEFF" + csv_data; 66 return csv_data_sjis; 67 } 68} 69 70

投稿2021/02/24 08:17

hatsuzo

総合スコア56

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

CSV

コードを見たところ、下記のように扱うようなので、

変数名CSV上の扱い
keyOrder列名
dtObject.values() がセル値

その前提でコードを書きました。

HTML

1<pre></pre> 2<script> 3'use strict'; 4function toCsv (keys, body) { 5 const header = keys.map(key => '"' + key.replace(/"/g, '""') + '"').join(); 6 7 body = body.map(function (obj) { 8 return this.map(key => '"' + String(obj[key]).replace(/"/g, '""') + '"').join(); 9 }, keys).join('\r\n'); 10 11 return header + '\r\n' + body; 12} 13 14 15const dt = [ 16 {cd:'A001', name:'鈴木', age:35}, 17 {cd:'A002', name:'佐藤', age:45}, 18 {cd:'A003', name:'"田中\n太郎"', age:55} 19]; 20 21const keyOrder = ['cd','name','age']; 22 23document.querySelector('pre').append(toCsv(keyOrder, dt)); 24</script>

RFC4180準拠。

new Map

連想配列の並び順が確保できなかったので、列の順番を付けるためにkeyOrderという配列を設けています。

順番が重要なら連想配列(という名の new Object)を使用するべきではありません。
new Map を使用しましょう。

Re: hatsuzo さん

投稿2021/02/23 11:29

think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatsuzo

2021/02/24 00:51 編集

think49さん 貴重なお時間を頂き、アドバイス有難うございました。 配列からCSVへの変換、シンプルに書けるのですね。 また、CSVの形式について、””は必ずしも必須ではないということ判りました。 昔から数字を文字属性として扱ってExcelで開かせたいような場合は、敢えて””で囲うべきと思っていたのですが、実際にExcelでそのように加工したCSVを開いても、敢えてテキスト形式として列ごとに属性指定しない限りは、結局は数字になってしまうので、あまり意味が無い、とは思っていました。 しかし、受け取るアプリによっては、必ずしもそうではない可能性もあり、また、区切り文字がフィールド内に入ってしまう可能性もあるので、文字列を””で囲うのは意味の無いことではないと思っています。 また、mapを使ったことのない私の理解不足かもしれませんが、見出しの文字列がデータ配列の中ではなく、前述したプロパティの中に定義されているため、せっかくですが、今回の事例ではこの方法では難しいと思います。
think49

2021/02/24 03:41 編集

CSVは単純なテキストデータで、セルに書式の概念はありません。 MS ExcelはCSVインポートする際に書式を指定出来ますが、他アプリでどのように扱うかはアプリ依存になります。 セル値を"で括るのは、カンマ/改行/ダブルコーテーション等のメタキャラクタを含む事が出来る以上の効果はありません。 > 見出しの文字列がデータ配列の中ではなく、前述したプロパティの中に定義されているため、 プロパティが定義されたオブジェクトデータのサンプルコードがあれば、対応出来るかもしれません。
hatsuzo

2021/02/24 06:03

有難うございました。 文言の意味がよく判っていないので、うまく説明ができていないみたいです。 jqGridとかCSVとかの本題ではないキーワードが登場してしまったので、判りにくくしていました。 要は、オブジェクトを持つ配列のインデックスを行、プロパティを列とみなした場合、 特定の列の値がキーワードに合致している行を探し、その行の別のプロパティを参照する、 つまりExcel関数でいうVlookupをする方法が判ればよいことに気づきました。 vlookup(キーの値、行列の範囲、返す列) データ実体の行ごとに、何度もプロパティを参照しなくてはいけないので、 あまりスマートな方法ではないですが、なんとか参照はできそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問