JavaScript:array.foreach()が機能しない場合があります
-
30-09-2019 - |
質問
これは私のコードスニペットであり、プログラムがforeachループを入力しません:
var ct = new Array();
ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};
ct.forEach(function (c){
document.getElementById("tmp").appendChild(document.createTextNode(c));
});
文字列( "me"、 "you")から整数に配列インデックスを変更すると、動作します。
var ct = new Array();
ct[0]= {"name" : "Jakub"};
ct[1]= {"name" : "stack"};
ct.forEach(function (c){
document.getElementById("tmp").appendChild(document.createTextNode(c));
});
あらゆる種類のインデックスを使用して配列を繰り返すソリューションを実装するのを手伝っていただけますか?私の目的は、指定された日付オブジェクトの値を保存することです。
のデータを使用します プロトビス ライブラリとAFAIK入力として配列が必要です。
Protovisの例で使用するデータ構造は、上記のこれよりも複雑です。
私のプロジェクトでは、Javabean経由でいくつかのオブジェクトのセットを送信します。これらのオブジェクトには、とりわけ日付が含まれています。私の目的は、Protovis Webサイトhttp:// vis.stanford.edu/protovis/ex/area.htmlに示されているこのようなグラフにこれらのオブジェクトを表示することです。
時間は水平軸と、特定の時間のオブジェクト数に垂直軸を使用します。 Afaik Protovisは、デフォルトモード(関数チェーンでの図のデータ入力としてのアレイのみが許可されているため、アレイを日付でソートしたい理由です。
編集:今のところ、メソッドを変更しました。文字列を配列キーとして保存する代わりに、私はフォローしています:これは私の元のコードスニペットです:
編集2: :いくつかの元の入力を追加しました:var result2 = {"h":{10 "documents":[11 {12 "biographicalcatigalies":[13]、14 "body": "ギリシャの保守的な政府は1955年の合意の調査を命じましたCIAとギリシャ軍の間で、戦争が発生した場合に侵略するワルシャワ協定軍と戦うためのゲリラネットワークの設立のためのギリシャ軍の間。」、15「記述子」:[16]、17「一般的な描写」:[18]、19 "GUID ":0、20"ヘッドライン ":「ゲリラ戦争の計画を調査するギリシャ」、21の「場所」:[22"ギリシャ "23]、24「名前」:[25]、26" onlinedescriptors ":[27]、 28 "OnlineLocations":[29]、30 "Online -ganizations":[31]、32 "OnlinePeople":[33]、34 "OnlineTitles":[35]、36 "組織":[37]、38 "People": [39]、40 "PublicationDate": "1990-11-21 00:00:00.0 CET"、41 "sourceFile": "0402635.xml"、42 "Taxonomicclassifiers":[43]、44 "タイトル":[45 ]、46「TypeOfMaterial」:[47]、48「スコア」:0.80242133 49}、
var resultTmp = new Array();
var i = 0;
var averageScore = 0;
var startDate = new Date();
var endDate = new Date(1700, 01, 01);
var docDate;
var actDate;
var tlk = new Array();
var av = 0;
var d = new Object();
result2.h.documents.forEach(function(c) {
averageScore += c.score;
if(typeof(c.publicationDate) != "undefined"){
docDate = c.publicationDate.split("-");
actDate = new Date(docDate[0], docDate[1]-1, docDate[2].split(" ")[0]);
if(actDate endDate){
endDate = actDate;
}
if(defined(tlk[actDate])){
av = tlk[actDate];
resultTmp[av].docs.push(c);
}
else {
d = new Object();
d.date = actDate;
d.docs = new Array();
d.docs.push(c);
resultTmp[i] = d;
tlk[actDate] = i;
i++;
}
}
});
i = 0;
var dates = [];
for(key in tlk){
if(key )
d = new Date(key);
if(isValidDate(d)){
dates[i] = new Date(key);
i++;
}
}
dates.sort(function (a, b) {
return a > b;
});
var ii = 0;
i = 0;
var ddocs;
var result = new Array();
for(i=0; i maxDocsPerDate){
maxDocsPerDate = d.docs.length;
}
result[i] = d;
}
編集3 上記のコードは現在機能しています:
一言で言えば、TLKアレイを使用してインデックスの日付を反映しています。 restrtmp配列の1つのインデックスの場合、その日付に関連するオブジェクトのセットを保存します。コードの次の部分では、日付を最古のものから最新のものに並べ替えて、結果を分類します。 resterTempのソートバージョンは、結果アレイにあります。
プロトビスのデータを次の方法で提示します。
vis.add(pv.Line)
.data(result)
.lineWidth(2)
.left(function(a) x(a.date))
.bottom(function(a) y(a.docs.length))
.add(pv.Dot)
.lineWidth(function(a) a.docs.length - (a.docs.length-1)/3)
.radius(function(a) a.docs.length * (a.docs.length/1.2))
.fillStyle(function(a) color(a.docs.length))
.event("click", function(a) Popup.show(a.docs))
.anchor("top").add(pv.Label)
.text(function(a) a.docs.length)
.textBaseline("bottom");
vis.render();
模範的な結果は、i.imgur.com / wodya.pngのように見えます
x軸とy軸を印刷するコードと、日付からグラフ幅までスケーリングするためのコードは含まれていませんでした。 Protovisの例ページで例を見つけることができます。
ところで:私はその部分でなぜ混乱しています:
for(key in tlk){
dates[i] = new Date(key);
i++;
}
最後の鍵として、私は「contains」を取得しますか?成功せずに、インターネットで答えを見つけようとしました。ベアーズは彼のコメントで、私がこのプロベルムを手に入れた理由は、私がアレイの特性を繰り返しているからだと説明しました。
解決
JavaScriptアレイは、数字のインデックス作成のみをサポートしています。あなたが書くとき
ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};
アドホックプロパティを追加しています me
と you
配列に;あなたは いいえ 配列に要素を追加します。 (も使用します new Array()
コンストラクターはちょっと奇妙です。配列が必要な場合は、を使用してください []
リテラル。)
ArrayではなくJavaScriptオブジェクトを使用する必要があるように聞こえますが、文字列インデックスのみをサポートすることに注意してください。
var ct = {};
ct['me'] = {name: 'Jakub'};
ct['you'] = {name: 'stack'};
for (var k in ct) {
document.getElementById('tmp', appendChild(document.createTextNode(ct[k]));
}
編集: 水平軸を時間として扱いたい場合は、もっと多くの仕事をする必要はありません。良い基本的な例があります ここ;コードを表示するには、ページソースを表示します。ここでのトリックは、データは実際には(オブジェクトの)配列であるが、X座標はデータアレイのインデックスとしてではなく、プロパティとして明示的に記載されていることです。配列内の各要素は次のようになります:
>>> data[0]
{x: /* some JavaScript date object */, y: /* some number */ }
出典:
- http://www.google.com/search?q = protovis+x-axis+time
- http://groups.google.com/group/protovis/browse_thread/thread/75ec1518692c2de5
- http://graphics.stanford.edu/~mbostock/dates/dates.html
編集2: あなたはまだアレイとオブジェクトについて混同しているようです。
あなたの「ところで」について:あなたが書くとき for(key in tlk) ...
すでに配列にあるキーを繰り返しています。それは配列をオブジェクトとして扱っています、そしてそれはあなたが望むものではありません!分かりますか contains
配列のプロパティを繰り返しているからです contains
関数はすべての配列に接続されていますか(プロトタイプ、または別の同様のライブラリを使用していますか?)。
ただし、基本的な問題は、配列にインデックスを付けていることです(tlk
)日付の使用。それは大きなノーです。もしそれでも tlk
オブジェクトはオブジェクトです。 文字列. 。私はあなたがしていることを本当に理解していません tlk
, 、しかし、私はあなたがそれをまったく必要としないと思います。入力データの形式は何ですか?あなたが私に入力の小さな例を私に与えることができれば、私はおそらくそれをどうするかをあなたに示すことができます。
また、あなたは本当に Array
と Object
コンストラクター。たとえば、使用します var tlk = []
それよりも var tlk = new Array();
, 、 と var d = {};
それよりも var d = new Object();
.
他のヒント
JavaScriptには連想配列がありません。ただし、オブジェクトにはプロパティという名前が付けられていますが、これは似ています。 foreach() インデックス付きプロパティを繰り返します。 a for...in
ループはここであなたを助けますが、一般的には使用を避けるでしょう for...in
アレイ上 なぜなら 名前付きプロパティを繰り返します。
for (var c in ct) {
if (ct.hasOwnProperty(c)) {
// do something
}
}
参照:
Array.prototype.forEach
メソッドは、数値インデックスで配列を横断します。
配列は「連想的」ではありません。値を持つプロパティの名前を付けたい場合は、単純なオブジェクトを使用し、 for-in
既存のプロパティを列挙するための声明:
var ct = {};
ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};
for (var prop in ct) {
if (ct.hasOwnProperty(prop)) {
alert(ct[prop]);
}
}
hasOwnProperty
メソッドが呼び出されます for-in
継承されるステートメントトラバースプロパティは、そのようにして、オブジェクトに物理的に存在するプロパティ(独自のプロパティ)のみを列挙します。
使用できます if (Object.prototype.hasOwnProperty.call(ct, prop))
それ以外の if (ct.hasOwnProperty(prop))
オブジェクトに名前が付けられたプロパティがある場合、追加の安全のために」hasOwnProperty
「、実行したい方法ではありません。