有没有更好的方法来循环这个对象?

时间:2017-10-11 16:15:05

标签: javascript jquery json

JSON

var data = {
  "countries": {
    "europe" : [{name: "England", abbr: "en"}, {name: "Spain", abbr: "es"}],
    "americas" : [{name: "Unites States"}],
    "asia" : [{name: "China"}]
  }
};

JS

for (k in data) {

  for (x in data[k]) {
    var cObj = data[k][x];

    $("#list").append(
      "<li><p>" + x + "</p></li>"
    );

    for (var i=0; i < cObj.length; i++) {
      $("#list").append(
        "<div> " + cObj[i].name + " </div>"
      );
    }
  }
}

我得到了预期的结果。但我觉得我使用太多的循环。这是我的jsfiddle示例。

5 个答案:

答案 0 :(得分:1)

你不需要外环,因为只有一个属性。

可以使用.map()替换最里面的循环来获取国家/地区的名称,并.join()将其与正确的HTML相关联(也可以在之前添加开始和结束divmap/join电话之后。

&#13;
&#13;
var data = {
  "countries": {
    "europe" : [{name: "England", abbr: "en"}, {name: "Spain", abbr: "es"}],
    "americas" : [{name: "Unites States"}],
    "asia" : [{name: "China"}]
  }
};


for (const x in data.countries) {
  const cObj = data.countries[x];

  $("#list").append(
    "<li><p>" + x + "</p><div>" +
    cObj.map(c => c.name).join("</div><div>") +
    "</div></li>"
  );
}
&#13;
#list > li > p {
  font-weight: bold;
}

#list > li > div {
  padding-left: 10px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id=list></ul>
&#13;
&#13;
&#13;

请注意,您将div个元素直接放在ul元素中,这在语义上是不正确的。您应该在生成li元素后关闭div

这是用for-in替换Object.entries().reduce()以限制DOM选择调用的数量。它还使用模板文字和参数解构来清理。

&#13;
&#13;
var data = {
  "countries": {
    "europe" : [{name: "England", abbr: "en"}, {name: "Spain", abbr: "es"}],
    "americas" : [{name: "Unites States"}],
    "asia" : [{name: "China"}]
  }
};


$("#list").append(
  Object.entries(data.countries).reduce((res, [x, a]) =>
    res + `<li>
             <p>${x}</p>
             <div>${a.map(c => c.name).join('</div><div>')}</div>
           </li>`, "")
);
&#13;
#list > li > p {
  font-weight: bold;
}

#list > li > div {
  padding-left: 10px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id=list></ul>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我对你的建议是摆脱裸循环!他们真的让代码更难阅读。而是使用forEachmap等功能。使用Array.prototype.forEach()

查看此代码段

var data = {
  "countries": {
    "europe" : [{name: "England", abbr: "en"}, {name: "Spain", abbr: "es"}],
    "americas" : [{name: "Unites States"}],
    "asia" : [{name: "China"}]
  }
};

Object.keys(data.countries).forEach(function (continent) {
  var countryList = data.countries[continent];
  $("#list").append("<li><p>" + continent + "</p></li>");
  countryList.forEach(function (countryObj) {
    $("#list li").append("<div>" + countryObj.name + "</div>");
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list"></div>

凭借良好的命名约定,它看起来更具可读性,不是吗?

答案 2 :(得分:1)

Here's a fiddle为你服务。这应该比原始帖子更高效,

var data = {
  "countries": {
    "europe" : [{name: "England", abbr: "en"}, {name: "Spain", abbr: "es"}],
    "americas" : [{name: "Unites States"}],
    "asia" : [{name: "China"}]
  }
};
const continents = Object.keys(data.countries);
for (let j = 0; j < continents.length; j += 1) {

    $("#list").append(
      "<li><p>" + continents[j] + "</p></li>"
    );

    let countries = Object.values(data.countries[continents[j]]);

    for (let i = 0; i < countries.length; i += 1) {
      $("#list").append(
        "<span> " + countries[i].name + " </span>"
      );
    }
  }

我比其他人更喜欢其他两个答案,他们看起来比我的表现更高,并且做得更少。

答案 3 :(得分:1)

我无法找到将其缩减为一个循环的方法,但您可以将其减少到两个,并提高可读性(正如之前的答案中已经提到的那样)。

RelativeLayout

Here is an updated jsFiddle

答案 4 :(得分:0)

我们可以利用jQuery的.append()接受数组的能力。这允许我们使用单个forEach循环(使用.map()将国家/地区包装在<li>代码中)。

这是在行动:

&#13;
&#13;
var data = {
  "countries": {
    "europe" : [{name: "England", abbr: "en"}, {name: "Spain", abbr: "es"}],
    "americas" : [{name: "Unites States"}],
    "asia" : [{name: "China"}]
  }
};

Object.keys(data.countries).forEach(country => {
  $("#list").append("<li><p>" + country + "</p></li>");
  $("#list").append(data.countries[country].map(place => "<div> " + place.name + " </div>"));
});

// Using arrow functions here but they could be replaced with standard callback function
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="list"></ul>
&#13;
&#13;
&#13;

如果需要,虽然我不确定它是否更优雅,但这两段内容都可以作为参数传递给单个.append()来电,如下所示:

Object.keys(data.countries).forEach(country => {
  $("#list").append(
    "<li><p>" + country + "</p></li>",
    data.countries[country].map(place => "<div> " + place.name + "</div>")
  );
});