【问题标题】:How to find the position of all array items from a loop如何从循环中找到所有数组项的位置
【发布时间】:2017-03-20 05:35:44
【问题描述】:

我是编程新手,所以如果这是一个简单的问题,我深表歉意。

我有一个独特的练习题,我不太确定如何解决:

我正在处理两个数组,两个数组都是从页面上的 HTML 元素中提取的,一个数组代表一堆状态,下一个数组代表它们的人口。问题的关键在于打印各州的名称及其低于平均水平的人口。

要查找并打印所有低于我使用此代码的平均值的总体:

  function code6() {
    // clears screen.
    clr();
    // both variables pull data from HTML elements with functions.
    var pop = getData2();
    var states = getData();
    var sum = 0;
    for( var i = 0; i < pop.length; i++ ){
      sum += parseInt( pop[i], 10 );
      var avg = sum/pop.length;
      if (pop[i] < avg) {
        println(pop[i]);

        // other functions used in the code to get data, print, and clear the screen.
        function getData() {
          var dataSource = getElement("states");
          var numberArray = dataSource.value.split('\n');
          // Nothing to split returns ['']
          if (numberArray[0].length > 0) {
            return(numberArray);
          } else {
            return [];
          }  
      }

    // Get the data from second data column
    function getData2() {
      var dataSource = getElement("pops");
      var numberArray = dataSource.value.split('\n');
      // Nothing to split returns ['']
      if (numberArray[0].length > 0) {
        return(numberArray);
      } else {
        return [];
      }  
    }

    // Clear the 'output' text area
    function clr() {
      var out = getElement("output");
      out.value = "";
    }

    // Print to the 'output' HTML element and ADDS the line break
    function println(x) {
      if (arguments.length === 0) x = '';
      print(x + '\n');
    }

现在我只需要知道如何获取数组中这些位置的值,这样我就可以从状态数组中提取相同的位置并并排显示它们。两个数组的项目数量相同。

我希望这是有道理的,并提前感谢任何有时间查看此内容的人。

最好的问候,

-E

【问题讨论】:

  • stackoverflow 搜索是你的朋友
  • clr()println() 不是 JavaScript。您确定您不是在询问与 JavaScript 完全不同的 Java 吗?如果没有,与这些函数相关的其余代码在哪里?
  • 大家好,感谢您的快速回复。
  • 我强烈建议你使用 eslint。您的代码不是很惯用,并且有很多明显的问题。 Eslint 将帮助您改进。
  • 请分享您的两个 getData() 函数返回的示例数据

标签: javascript arrays loops


【解决方案1】:

很难说出你想要完成什么,但我猜你会追求类似的东西:

'use strict'

function code6() {
  const populations = ['39000000', '28000000', '21000000'];
  const stateNames = ['california', 'texas', 'florida'];
  const states = populations.map((population, i) => ({
    'name': stateNames[i],
    'population': Number(population),
  }));

  const sum = states.reduce((sum, state) => sum + state.population, 0);
  const average = sum / populations.length;
  states
      .filter(state => state.population < average)
      .forEach(state => {
        const name = state.name;
        const population = state.population;
        console.log(`state name: ${name}, population: ${population}`);
      });
}

// run the code
code6();
// state name: texas, population: 28000000
// state name: florida, population: 21000000

我冒昧地将您的代码重构为更现代 (es6) 和惯用的代码。我希望它不会让你感到困惑。如有任何问题,请随时提出。

简而言之,您应该使用:

  • 文件顶部的“使用严格”
  • 常量/让
  • 使用 map/filter/forEach/reduce 来迭代列表。
  • 使用有意义的名称

,你应该避免:

  • 经典的索引 for 循环
  • parseInt

,而且几乎从未使用过:

  • 变量

【讨论】:

  • 不错的解决方案,但有两件事。首先,我认为你需要.filter(state =&gt; state.population &lt; avg)(不是>)。其次,有什么理由不用.forEach(state =&gt; console.log(state name: ${state.name}, population: ${state.population}))`替换最后一个子句?我没有看到临时变量添加了任何有用的东西。
  • 你是对的,它应该小于 avg,我的错;我会解决的。
  • 至于你关于${state.name} 的观点,它会使复合字符串行不适合80 个字符,这意味着它的方式很长,IMO。我也认为它的可读性会降低。我会说它主要是一种风格。我更喜欢多行而不是长行。
  • 我曾短暂考虑过使用解构,即({name, population}) = &gt; {},但由于某种原因,这不适用于我的节点安装,我认为考虑到这是对初学者。
【解决方案2】:

如果您的states 数组是用与您的pop 对应的索引构建的,如下所示:

states; //=> ['Alabama', 'Alaska', 'Arizona', ...]
pop; //=> [4863300, 741894, 6931071, ...]

那么您可以简单地更新您的打印语句以将其考虑在内:

  if (pop[i] < avg) {
    println(state[i] + ': ' + pop[i]);
  }

或者类似的。

但是,使用共享索引可能是一种非常脆弱的数据使用方式。您能否重新考虑您的 getDatagetData2 函数并将它们组合成一个返回类似于以下结构的结构?

states; //=> [
        //     {name: 'Alabama', pop: 4863300}
        //     {name: 'Alaska', pop: 741894},
        //     {name: 'Arizona', pop: 6931071},
        //    ...]

这将需要更改上面的代码以使用这些对象的 pop 属性,但它可能更健壮。

【讨论】:

  • 这太棒了!非常感谢你的帮助。我会努力变得更好,并更改我的代码以反映您的建议。
【解决方案3】:

如果您的 popstate 看起来像:

var state = ['state1', 'state2', ...];
var pop = ['state1 pop', 'state2 pop', ...];

那么首先,avg 已经错了。 sum 的值与将 avg 的公式转换为 sum as of iteration / array length 而不是 sum of all pops / array length 的循环一起运行。您应该事先计算平均值。 array.reduce 将成为你的朋友。

var average = pop.reduce(function(sum, val){return sum + val;}, 0) / pop.length;

现在对于您的过滤操作,您可以:

  1. 使用array.map 将两个数组压缩为一个数组。
  2. 使用array.filter过滤结果数组。
  3. 最后,使用array.forEach 循环遍历结果数组

这里是示例代码:

var states = ['Alabama', 'Alaska'];
var pop = [4863300, 741894];
var average = pop.reduce(function(sum, val){return sum + val;}) / pop.length;

console.log('Average: ' + average);

states.map(function(state, index) {

  // Convert 2 arrays to an array of objects representing state info
  return { name: state, population: pop[index] };
  
}).filter(function(stateInfo) {
  console.log(stateInfo);

  // Filter each item by returning true on items you want to include
  return stateInfo.population < average;
  
}).forEach(function(stateInfo) {

  // Lastly, loop through your results
  console.log(stateInfo.name + ' has ' + stateInfo.population + ' people');
  
});

【讨论】:

  • 非常感谢您的帮助和建议,我并没有真正认为我的平均水平不正确,但您的建议非常有意义。我已经学习 Javascript 大约 7 周了,所以我能学到的任何东西都非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 2016-06-25
  • 2018-03-09
相关资源
最近更新 更多