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));
});
您能帮我实施用各种索引在阵列上迭代的解决方案吗?我的目的是存储给定日期对象的值。
我将数据用于 Protovis 库和afaik需要一个数组作为输入。
我在Protovis示例中使用的数据结构比上面显示的更复杂。
在我的项目中,我通过Javabean发送一些对象。这些对象包括日期。我的目的是在图中显示这些对象,并在Protovis网站上介绍http:// vis.stanford.edu/protovis/ex/earke.html。
我将在时间内使用水平轴,并在给定时间内使用垂直轴。这就是为什么我想将数组按日期排序,因为Afaik Protovis仅允许数组作为在默认模式下的数据输入 - 函数链接。
编辑:现在我更改了方法。我确实要说的是:此处是我的原始代码段:而不是将字符串存储为数组键:
Edit2: :我添加了一些原始输入:var result2 = {“ h”:{10“ documents”:[11 {12“传记计算”:[13],14“身体”:“希腊的保守政府已下令对1955年的协议进行调查在中央情报局和希腊军队之间建立了一个游击网络,以战斗在战争时与入侵的华沙条约部队作战。 “:0,20“标题”:“希腊调查游击战争计划”,21“位置”:[22“希腊23],24”名称“:[25],26“ OnlinedEscriptors”:[27],[27],,,,, 28“ OnlineLacations”:[29],30“在线组织”:[31],32“在线peple”:[33],34“ Onlinetitles”:[35],36“组织”:[37],38“ PEOPLE”人: [39],40“ PublicationDate”:“ 1990-11-21 00:00:00.0:00.0 CET”,41“ sourceFile”:“ 0402635.xml”,42“ saxonomicicclassifiers”:[43],44“,44”标题:[45 ],46“类型材料”:[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;
}
edit3 上面的代码现在正常工作:
简而言之:我使用TLK数组来反映索引的日期。对于ResultTMP数组中的一个索引,我存储了日期和与该日期相关的对象集。代码的下一部分我用来对最新的日期进行排序,然后类似地对ResultTemp进行排序。 ResultTemp的排序版本在结果数组中。
我以下面的方式介绍了Protovis的数据:
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++;
}
作为最后的钥匙,我得到了“包含”?试图在互联网上找到答案,而没有成功。 Bears在他的评论中解释说,我得到这个问题的原因是因为我对阵列的属性进行了迭代。
解决方案
JavaScript数组仅支持按数字索引。当你写时
ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};
您正在添加临时属性 me
和 you
到阵列;你是 不是 将元素添加到数组中。 (也使用 new 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/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没有关联阵列,par se。但是,对象命名属性,这是相似的。 foreach() 只会迭代索引属性。一种 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
”,将不是您要执行的方法。