首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关联数组操作斗争

关联数组操作斗争
EN

Stack Overflow用户
提问于 2015-04-11 09:06:33
回答 2查看 73关注 0票数 0

我试图理解下面的代码中所发生的事情:

代码语言:javascript
复制
var dataset = [
    {source: "Microsoft", target: "Amazon", type: "licensing"},
    {source: "Microsoft", target: "HTC", type: "licensing"},
    {source: "Samsung", target: "Apple", type: "suit"},
    {source: "Motorola", target: "Apple", type: "suit"},
    {source: "Nokia", target: "Apple", type: "resolved"},
    {source: "HTC", target: "Apple", type: "suit"},
    {source: "Kodak", target: "Apple", type: "suit"},
    {source: "Microsoft", target: "Barnes & Noble", type: "suit"},
    {source: "Microsoft", target: "Foxconn", type: "suit"},
    {source: "Oracle", target: "Google", type: "suit"},
    {source: "Apple", target: "HTC", type: "suit"},
    {source: "Microsoft", target: "Inventec", type: "suit"},
    {source: "Samsung", target: "Kodak", type: "resolved"},
    {source: "LG", target: "Kodak", type: "resolved"},
    {source: "RIM", target: "Kodak", type: "suit"},
    {source: "Sony", target: "LG", type: "suit"},
    {source: "Kodak", target: "LG", type: "resolved"},
    {source: "Apple", target: "Nokia", type: "resolved"},
    {source: "Qualcomm", target: "Nokia", type: "resolved"},
    {source: "Apple", target: "Motorola", type: "suit"},
    {source: "Microsoft", target: "Motorola", type: "suit"},
    {source: "Motorola", target: "Microsoft", type: "suit"},
    {source: "Huawei", target: "ZTE", type: "suit"},
    {source: "Ericsson", target: "ZTE", type: "suit"},
    {source: "Kodak", target: "Samsung", type: "resolved"},
    {source: "Apple", target: "Samsung", type: "suit"},
    {source: "Kodak", target: "RIM", type: "suit"},
    {source: "Nokia", target: "Qualcomm", type: "suit"}
];

var nodes = {};
update(dataset);

function update(links){
    var i = 1;
    links.forEach(function(link){
        // Pre iteration checks
        console.log(i);
        console.log(link.source);
        console.log(nodes[link.source]);
        // Observations – initial dataset is being overwritten? 

        // Should the following be read as “if one evaluates to true, do both?”
        link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, linkCount:0}); // Initialize new nodes with zero links
        link.source.linkCount++;

        // Post iteration checks
        console.log(link.source);
        console.log(nodes[link.source]); // This is undefined if link.source is now an object. This is effectively saying console.log(nodes[object])
        console.log(nodes[link.source.name]); // This now says console.log(nodes["Microsoft"]) (for ex)
        i++;
    });
}

如果我在每次迭代中写下我认为正在发生的事情,我会看到以下内容:

  • 迭代1:"Microsoft" = nodes["Microsoft"]?假。
  • 所以设置nodes["Microsoft"] = { name: "Microsoft", linkCount: 0 }
  • 增量底层节点linkCount + 1 so nodes["Microsoft"] = { name: "Microsoft", linkCount: 1 }
  • 迭代2:"Microsoft" = nodes["Microsoft?"]?是真的。
  • 增量底层节点linkCount + 1 so nodes["Microsoft"] = { name: "Microsoft", linkCount: 2 }
  • 迭代3:"Samsung" = nodes["Samsung"]?假。
  • 所以设置nodes["Samsung"] = { name: "Samsung", linkCount: 0 }
  • 增加底层节点linkCount + 1 so nodes["Samsung"] = { name: "Samsung", linkeCount: 1 }

我怀疑我的困惑与OR (||)操作符的工作方式有关。我的想法是,如果LHS评估为错误,跳过它,做RHS。这样做不对吗?

编辑:

如果我只看第一次迭代;

代码语言:javascript
复制
dataset[0].source = nodes[dataset[0].source] || (nodes[dataset[0].source] = { name: dataset[0].source })

我们希望双方都能实现。dataset.source应该设置为节点[dataset.source],我们希望为节点[dataset.source]设置“值”。

如果我试着像这样跑;

代码语言:javascript
复制
dataset[0].source = nodes[dataset[0].source];
nodes[dataset[0].source] = { name: dataset[0].source };

然后,第一行运行良好,大概是将"Microsoft“替换为指向节点“微软”的指针,然后尝试用未定义的dataset.source值更新节点”microsoft“的名称,该值仅将节点”microsoft“的名称值设置为未定义。

如果我像这样尝试代码;

代码语言:javascript
复制
dataset[0].source = nodes[dataset[0].source] || nodes[dataset[0].source] = { name: dataset[0].source };

然后,我得到了错误"Uncaught :无效的左方在赋值“-不确定为什么会这样?

最后如果我试着

代码语言:javascript
复制
dataset[0].source = nodes[dataset[0].source] || (nodes[dataset[0].source] = { name: dataset[0].source });

在RHS周围加上括号,所有这些都可以正常工作。dataset.source是对象,节点[dataset.source]也是对象。

对于这三种不同的代码结构,这种行为发生的原因最终是我所不理解的,特别是为什么第三种代码能够工作。

EN

回答 2

Stack Overflow用户

发布于 2015-04-11 09:19:21

二元逻辑运算符 ||也被称为“默认”运算符。它通常不返回布尔值,而是返回第一个值,除非它是falsy,在这种情况下返回第二个值。换句话说,

a || b

字面上返回a或b。

例如,null || 4返回4。

是的,如果左侧为真,则完全忽略右侧表达式(解析但不求值)。

至于link.source,通过尝试为该字符串分配一个属性,代码将该字符串隐式装箱到一个对象中。字符串和数字都可以用这种方式装箱,既可以使用继承的方法和属性(例如,link.source.length来获取字符串的长度),也可以为它们分配新的方法和属性。它们通过这样做来保留它们的类型,这与如果您执行new String(link.source)时所发生的情况不同:这会创建一个在各个方面都类似于一个的真正对象。

票数 0
EN

Stack Overflow用户

发布于 2015-04-11 09:39:25

我不太清楚混淆在哪里,但代码是这样工作的:

代码语言:javascript
复制
var dataset = [ /*data*/]
var nodes = {}

update(dataset);

正如预期的那样,这是将大量数据和节点初始化为空对象文本,然后调用update函数。

-

代码语言:javascript
复制
function update(links) {
    var i = 1;
    links.forEach(function(link)
    {
        //content
        i++;
    });
}

这是对数组的迭代,增加了i的值。

这里有两个稍微切线的点--传递给foreach的回调不是自己递增,而是将索引作为其第二个参数;如果支持旧的浏览器,因为它不适用于前IE8浏览器,那么要小心使用forEach。

代码语言:javascript
复制
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, linkCount:0});    // initialize new nodes with zero links
link.source.linkCount++;

这是循环code.The惰性"OR“操作符的关键所在--就像您提到的那样--如果左边是真实的,那么它就不会计算第一部分,所以

代码语言:javascript
复制
true || foo();

永远不会评估"foo“函数。因此,如果nodeslink.source确实存在(并且是真实的,但定义的对象总是真实的),那么它将忽略第二部分,并将该值分配给link.source,覆盖现有的数据集。

如果左边的表达式是falsey,那么它将计算您的右侧,并在节点中创建节点并将其分配给link.source。

这意味着在代码运行结束时,节点将成为一个具有包含linkCounts和名称的属性的对象;数据集将是相同的数组,但是每个对象的源属性由相同的linkCount/name对象关联。

-

我不完全确定您希望您的代码如何工作,所以不确定这与您预期的运行有什么不同。

有一件事可能是问题,那就是您讨论比较link.source和nodeslink.source,但是在您编写的代码中没有出现这种情况,因为您使用的是赋值运算符,而不是双或三等号("==“或"===") --哪个是比较运算符?如果您想这样做,那么相关的行将是:

代码语言:javascript
复制
(link.source == nodes[link.source]) || (nodes[link.source] = {name: link.source, linkCount:0});

我对在这种诡计中使用or操作符持谨慎态度,因为聪明的代码通常很难读懂,如果这就是您想要的,我倾向于使用标准if语句来提高可读性:

代码语言:javascript
复制
if(link.source !== nodes[link.source]) {
    nodes[link.source] = {name: link.source, linkCount:0}
}

然而,如果这是你想要的,那么它会给你一个奇怪而毫无意义的输出.=\

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29576059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档