0

这是我的代码片段,程序没有进入 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/area.html 上显示这些对象。

我将使用水平轴表示时间,垂直轴表示给定时间的对象数量。这就是为什么我想让数组按日期排序的原因,因为 AFAIK protovis 在默认模式下仅允许数组作为其图表的数据输入 - 函数链接。

编辑:现在我改变了方法。我没有将字符串存储为数组键,而是执行以下操作:特此是我的原始代码片段:
edit2:我添加了一些原始输入: var result2 = {"h": { 10 "documents": [ 11 { 12 "biographicalCategories": [ 13 ], 14 "body": "希腊保守政府已下令对 1955 年的协议进行调查中央情报局和希腊军方之间建立游击队网络,以在发生战争时与入侵的华约部队作战。”,15 个“描述符”:[16],17 个“通用在线描述符”:[18],19 个“guid ": 0, 20 "headline": "希腊调查游击战争计划", 21 "locations": [22 "GREECE" 23], 24 "names": [25], 26 "onlineDescriptors": [27], 28 个“在线位置”:[29],30 个“在线组织”:[31],32 个“在线人”:[33],34 个“在线标题”:[35],36 个“组织”:[37],38 个“人”:[39],40 个“发布日期”:“1990-11-21 00:00:00.0 CET”,41 个“源文件” : "0402635.xml", 42 "taxonomicClassifiers": [ 43 ], 44 "titles": [ 45 ], 46 "typesOfMaterial": [ 47 ], 48 "score": 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 在他的评论中解释说,我得到这个问题的原因是因为我正在迭代数组的属性。

4

3 回答 3

2

解析,JavaScript 没有关联数组。但是,对象具有命名属性,这是相似的。 forEach()只会遍历索引属性。循环将在这里为您提供for...in帮助,尽管通常您会避免for...in在数组上使用,因为它也会迭代命名属性。

for (var c in ct) {
    if (ct.hasOwnProperty(c)) {
        // do something
    }
}

也可以看看:

于 2010-08-23T14:29:38.913 回答
2

JavaScript 数组仅支持按数字索引。当你写

ct["me"]= {"name" : "Jakub"};
ct["you"]= {"name" : "stack"};

您正在向数组添加临时属性meyou没有向数组添加元素。(也使用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 */ }

资料来源:


编辑 2:您似乎仍然对数组与对象混淆。

关于您的“顺便说一句”:当您编写时,for(key in tlk) ...您正在遍历数组中已经存在的键。那就是将数组视为一个对象,这不是您想要的!您看到contains是因为您正在迭代数组的属性,并且contains是一个附加到每个数组的函数(您使用的是原型,还是其他类似的库?)。

然而,基本问题是您tlk使用 Date 对数组 ( ) 进行索引。这是一个很大的禁忌。即使tlk是一个对象,因为您只能使用字符串索引对象。我真的不明白你在做什么tlk,但我认为你根本不需要它。你的输入数据的形式是什么?如果你能给我一个输入的小例子,我可能会告诉你如何处理它。

此外,您应该真正使用数组和对象文字而不是ArrayandObject构造函数。例如,使用var tlk = []而不是var tlk = new Array();var d = {};而不是var d = new Object();

于 2010-08-23T14:30:01.720 回答
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”的属性,则不会是您要执行的方法。

于 2010-08-23T14:30:26.213 回答