这是我的代码片段,程序不会进入foreach循环:
var ct = new Array();
ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};
ct.forEach(function (c){
document.getElementById("tmp").appendChild(document.createTextNode(c));
});
当我将数组索引从字符串(“我”,“你”)更改为整数时,它可以工作:
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 / area.html上显示。
我将使用横轴表示时间,垂直轴表示给定时间内的对象数。这就是为什么我想让数组按日期排序,因为AFAIK protovis只允许数组作为默认模式下的图表的数据输入 - 函数链。
编辑:
现在我改变了方法。不是将字符串存储为数组键,而是执行以下操作:
特此是我原来的代码片段:
edit2 :我添加了一些原始输入:
var result2 = {“h”:{
10“文件”:[
11 {
12“传记类别”:[
13],
14“身体”:“希腊保守派政府已经下令调查1955年C.I.A.与希腊军方达成的协议,以建立一个游击网络,以便在发生战争时与入侵的华沙条约部队作战。”,
15“描述符”:[
16],
17“generalOnlineDescriptors”:[
18],
19“guid”:0,
20“标题”:“希腊调查游击战争计划”,
21个“位置”:[
22“希腊”
23],
24“名字”:[
25],
26“onlineDescriptors”:[
27],
28“onlineLocations”:[
29],
30“onlineOrganizations”:[
31],
32“onlinePeople”:[
33],
34“onlineTitles”:[
35],
36个“组织”:[
37],
38“人”:[
39],
40“publicationDate”:“1990-11-21 00:00:00.0 CET”,
41“sourceFile”:“0402635.xml”,
42“taxonomicClassifiers”:[
43],
44个“头衔”:[
45],
46“typesOfMaterial”:[
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++;
}
作为最后一把钥匙,我得到“包含”?试图在互联网上找到答案,但没有成功。 熊在他的评论中解释说,我得到这个问题的原因是因为我正在迭代数组的属性。
答案 0 :(得分:2)
JavaScript没有关联数组,参见。但是,对象具有命名属性,这是类似的。 forEach()只会迭代索引属性。 for...in
循环可以在这里为您提供帮助,但通常您会避免在数组上使用for...in
,因为它也会在命名属性上进行迭代。
for (var c in ct) {
if (ct.hasOwnProperty(c)) {
// do something
}
}
另见:
答案 1 :(得分:1)
JavaScript数组仅支持按编号索引。当你写
ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};
您正在向阵列添加ad-hoc属性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]));
}
编辑:如果您想将横轴视为时间,您实际上不需要做更多的工作。有一个很好的基本例子here;查看页面源以查看代码。这里的技巧是,虽然数据确实是一个数组(对象),但x坐标显式地表示为属性而不是数据数组中的索引。数组中的每个元素都如下所示:
>>> data[0]
{x: /* some JavaScript date object */, y: /* some number */ }
来源:
编辑2:关于数组与对象,你似乎仍然混淆不清。
关于你的“BTW”:当你写for(key in tlk) ...
时,你正在迭代已经在数组中的键。这是将数组视为一个对象,而这不是你想要的!您看到contains
,因为您正在迭代数组的属性,而contains
是附加到每个数组的函数(您使用的是原型还是其他类似的库?)。
然而,基本问题是您使用Date索引到数组(tlk
)。这是一个很大的禁忌;即使tlk
是一个对象,因为您只能使用字符串索引对象。我真的不知道你在tlk
做了什么,但我认为你根本不需要它。输入数据的形式是什么?如果你能给我一个输入的小例子,我可以告诉你如何处理它。
此外,您应该使用数组和对象文字而不是Array
和Object
构造函数。例如,使用var tlk = []
而不是var tlk = new Array();
和var d = {};
而不是var d = new Object();
。
答案 2 :(得分:1)
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
”的属性,则不会是您要执行的方法。