找到JavaScript 2d学生得分中的最高平均值

时间:2018-02-20 09:01:39

标签: javascript multidimensional-array

昨天,我遇到了这个面试问题。最初,它似乎很容易,至少在逻辑上。 但不知何故,我无法在JavaScript中使用它。

这是学生成绩的二维数组,学生姓名可能会重复多次。如果是这种情况,请将所有分数相加并除以出现次数以找到平均值,如有必要,请运行Math.floor。

var arr = [
    ["Bobby","87"],
    ["Charles","100"],
    ["Eric","65"],
    ["Charles","22"],
    ["Charles","37"],
    ["Eric","49"]]

因此,Charles平均得分为Math.floor((100+22+37)/3) = 53 而且,对于Eric,它将是Math.floor((65+49)/2) = 57

所以最高平均值为["Bobby","87"]

到目前为止,我的尝试毫无结果..

var op_arr = [];
arr.each(function(item) {
    var sum = 0;
    var itemCount = 1;
    var checkFlag = isItemInArray(arr,item);
    if(checkFlag) {
        itemCount++;
        sum += item[1];
    }
});
function isItemInArray(array,item) {
    for(let i = 0;i < array.length; i++) {
        if(array[i][0] === item[0]) {
            return array[i];
        }
    }
    return false;
}

但这不起作用。 请帮助我并解释逻辑。

7 个答案:

答案 0 :(得分:5)

我会使用一些代码将列表转换为哈希映射,因为可能有多个同一个学生。

var arr = [
    ["Bobby","87"],
    ["Charles","100"],
    ["Eric","65"],
    ["Charles","22"],
    ["Charles","37"],
    ["Eric","49"]
];

var scores = {};

for (var i = 0; i < arr.length; i++) {
    var student = arr[i];

    if (!scores.hasOwnProperty(student[0]))
        scores[student[0]] = []

    scores[student[0]].push(student[1])
}

结果应为:

{
    "Bobby": ["87"],
    "Charles": ["100", "22", "37"],
    "Eric": ["65", "49"]
}

现在你可以对对象进行第二次传递来计算平均值

for (var key in scores) {
    if (!scores.hasOwnProperty(key)) continue;

    var total = scores[key].reduce(function(next, cur) { 
        return next + parseInt(cur);
    }, 0);

    scores[key] = Math.floor(total / scores[key].length);
}

console.log(scores);

我确信你可以使用ES6功能让它变得更优雅,但这可以让你了解一个解决方案。

答案 1 :(得分:0)

您可以先获取每个人的所有平均值,然后获得临时结果的最高平均值。

如果不止一个人的得分相同,则包括所有人。

&#13;
&#13;
var array = [["Bobby", "87"], ["Charles", "100"], ["Eric", "65"], ["Charles", "22"], ["Charles", "37"], ["Eric", "49"]],
    highest = array
        .reduce(function (r, a) {
            var i = r.findIndex(b => a[0] === b[0]);
            if (i !== -1) {
                r[i][1] = (r[i][1] * r[i][2] + +a[1]) / ++r[i][2];
            } else {
                r.push(a.concat(1));
            }
            return r;
        }, [])
        .reduce(function (r, a, i) {
            if (!i || r[0][1] < a[1]) {
                return [a.slice(0, 2)];
            }
            if (r[0][1] === a[1]) {
                r.push(a.slice(0, 2));
            }
            return r;
        }, []);

console.log(highest);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以遵循此方法

  • 整理使用reduce
  • 分数数组中名称的所有分数
  • 使用map使用reduce再次使用var fnSumAvgArray = (arr) => arr.reduce( ( a, c ) => a + c, 0 )/arr.length; var arr = [ ["Bobby","87"], ["Charles","100"], ["Eric","65"], ["Charles","22"], ["Charles","37"], ["Eric","49"]]; var output = Object.values( arr.reduce( (a,c) => ( a[c[0]] = (a[c[0]] || { name : c[0], scores : [] }), //check if accumulator already has been initialized for this name or else intialize a[ c[ 0 ] ].scores.push ( +c[1] ), //push the score into the name based score array a ) , {}) ) //return the accumulator .map( s => ( s.avg = fnSumAvgArray(s.scores), s )); console.log( output );计算>得分

<强>演示

&#13;
&#13;
git clone https://github.com/karelzak/util-linux.git
&#13;
&#13;
&#13;

答案 3 :(得分:0)

&#13;
&#13;
    var arr = [
    ["Bobby","87"],
    ["Charles","100"],
    ["Eric","65"],
    ["Charles","22"],
    ["Charles","37"],
    ["Eric","49"]];
    var x, students=[], counter=[], scoreSums=[], name, i=0;
    for(x in arr) {
      name = arr[x][0];
      j = students.indexOf(name);
      if(j < 0) {
        students[i] = name;
        counter[i] = 1;
        scoreSums[i] = parseInt(arr[x][1]);
        i++;
      } else {
        scoreSums[j] += parseInt(arr[x][1]); 
        counter[j]++;
      }
    }
    
    var maxMean = 0, mean;
    for(i=0; i<students.length; i++) {
      mean = scoreSums[i] / counter[i];
      if(mean > maxMean) {
        name = students[i];
        maxMean = mean;
      }
    }
    document.getElementById('maxMean').innerHTML='Highest average is '+ name+' at '+maxMean;
    console.log(name, maxMean);
&#13;
<div id="maxMean"></div>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

这是一个围绕房屋的地方&#39;做法。这是一个稍微长一点的写出来,但我认为这是人类可读的,应该有助于这个概念。

我评论了下面的代码。

&#13;
&#13;
var arr = [
  ["Bobby", "87"],
  ["Charles", "100"],
  ["Eric", "65"],
  ["Charles", "22"],
  ["Charles", "37"],
  ["Eric", "49"]
];

let objects = [];
let names = [];

for (let item of arr) {
  // Get unique names
  if (names.indexOf(item[0]) <= 0) {
    names.push(item[0]);
  }
  // Create object rather than array
  let score = {
    name: item[0],
    score: parseInt(item[1])
  }
  objects.push(score);
}
// Work out average based on name
function countScore(name) {
  let count = 0;
  let total = 0;
  for (let object of objects) {
    if (object.name === name) {
      count += 1;
      total += object.score
    }
  }
  let avgScore = total / count;
  console.log(name + ': ' + avgScore)
}
// Run function for each unique name
for (let name of names) {
  countScore(name);
}
&#13;
&#13;
&#13;

我希望你觉得这很有用。

答案 5 :(得分:0)

let findMaxAvg = (arr) => {
let studmap = new Map();
    arr.forEach((item,ind) => {
        let [name,score] = [item[0],item[1]];
        !studmap.has(name) ? studmap.set(name,[score,1]) : studmap.set(name, 
            [studmap.get(name)[0]+score,studmap.get(name)[1]+1])
    });
    return Math.max(...[...studmap.values()].map(sdata => 
  Math.round(sdata[0]/sdata[1])));

}

var arr = [
["Bobby","87"],
["Charles","100"],
["Eric","200"],
["Charles","22"],
["Charles","37"],
["Eric","49"]];
console.log(findMaxAvg(arr));

答案 6 :(得分:0)

根据上面提供的解决方案,您可以通过多种方式解决此问题。我之前也遇到过这个问题,我用过

<块引用>

Map()

收集所有学生和他们的分数并返回带有 [name, average] 的数组。

const scores = [['brian', 80], ['brian', 90], ['brian', 65], ['robhy', 85], ['robhy', 75], ['ryan', 75], ['murphy', 85]];

const calculateHigestAvg = (scores)=>{

    let studentObj = new Map();
    let score = [];

    for (var i = 0; i < scores.length; i++) {
        if (studentObj.has(scores[i][0])) {
            const studentScoreArr = studentObj.get(scores[i][0])
            studentScoreArr.push(scores[i][1]);
            studentObj.set(scores[i][0], studentScoreArr);
        } else {
            studentObj.set(scores[i][0], [scores[i][1]]);
        }
    }
    return Array.from(studentObj.entries())
        .map((item, index)=>{
            return [item[0], Math.floor(item[1].reduce((a, b) => a + b) / item[1].length)]
    }
    , 0)        
}

calculateHigestAvg(scores);

// results
[["brian", 78],["robhy", 80],["ryan", 75],["murphy", 85]]