2

目标

我正在尝试制作一个函数,该函数将采用“投票”数组并返回一个对象,该对象包含每个“候选人”获得 1 分的次数。

例如一个数组,例如:

[
    {
        "blue": 1,
        "red": 3,
        "purple": 2,
        "yellow": 4
    },
    {
        "blue": 2,
        "red": 3,
        "purple": 4,
        "yellow": 1
    },
    {
        "blue": 1,
        "red": 2,
        "purple": 4,
        "yellow": 3
    },
    {
        "blue": 3,
        "red": 4,
        "purple": 2,
        "yellow": 1
    }
];

应该返回一个对象

{
    "blue": 2,
    "red": 0,
    "purple": 0,
    "yellow": 2
}

当前代码

目前我已经编写了函数

// adds up the first choice results from raw data
// return object containing number of first choice votes each candidate received
const add_first_choices = function (raw_data) {
    // create object to store number of first choices
    const storage_obj = empty_candidate_obj(raw_data);

    // loop through results, adding first choices to storage_obj
    raw_data.forEach(function (single_voter_obj) {
        Object.values(single_voter_obj).forEach(function (value) {
            if (value === 1) {
                storage_obj[getKeyByValue(single_voter_obj, value)] += 1;
            }
        });
    });
    return storage_obj;
};

它使用以下两个其他功能

// returns object of candidate names, each with value of 0
const empty_candidate_obj = function (raw_data) {
    const input_data = raw_data;
    let first_vote = input_data[0];
    const keys = Object.keys(first_vote);
    keys.forEach(function (key) {
        first_vote[key] = 0;
    });
    return first_vote;
};

// returns key from object value
const getKeyByValue = function (object, value) {
    return Object.keys(object).find((key) => object[key] === value);
};

问题

将上述数组输入我的函数时,它返回

{
    blue: 1,
    red: 0,
    purple: 0,
    yellow: 2
}

=> 不像预期的那样!

你知道我做错了什么吗?

感谢您的任何回复:)

4

4 回答 4

2

问题在于这一行:

const input_data = raw_data;

复制对象数组是有问题的,因为复制数组不会自动生成对象的新副本。它只是一个引用原始对象的新数组,因此如果您更改新数组中的对象,您将更改原始对象。

因此,您还需要制作对象的新副本

const input_data = raw_data.map(obj => ({...obj}));

您可以使用 稍微简单地解决您的问题reduce

const data = [{"blue":1,"red":3,"purple":2,"yellow":4},{"blue":2,"red":3,"purple":4,"yellow":1},{"blue":1,"red":2,"purple":4,"yellow":3},{"blue":3,"red":4,"purple":2,"yellow":1}];

// We initialise the `reduce` with a new `{}` object,
// which is updated with each iteration.
// `acc` is the accumulator, `c` is the current element
const result = data.reduce((acc, c) => {

  // For each object in the array we grab the key and value
  Object.entries(c).forEach(([ key, value ]) => {

    // If our initial object doesn't already have a key
    // that matches, create one and set it to zero
    acc[key] = acc[key] || 0;

    // And if the value is one, increase the value of that property
    if (value === 1) acc[key]++;
  });

  // Make sure to return the initial object
  // for the next iteration
  return acc;
}, {});

console.log(result);

于 2021-06-07T16:50:04.363 回答
1

关于您的代码,问题出在这行 empty_candidate_obj 函数中

  let first_vote = input_data[0];

更新您的代码以发送副本

let first_vote = {...input_data[0]};

对象在参考上起作用。所以就像您的数据集值的第一个对象也使用空对象更新为 0

于 2021-06-07T17:02:31.600 回答
0

试试这个功能:

function candidateScore1Times(array) {
  const newObj = {}

  for (const score of array) {
    Object.keys(score).forEach(elem => {
      if (newObj[elem] != null)  {
        if (score[elem] == 1) {
          newObj[elem]++
        }
      } else {
        score[elem] == 1 ? newObj[elem] = 1 : newObj[elem] = 0
      }
    })
  }
  return newObj
}

于 2021-06-07T17:10:53.133 回答
0

您可能想使用这样的减速器:

const results = [
    {
        "blue": 1,
        "red": 3,
        "purple": 2,
        "yellow": 4
    },
    {
        "blue": 2,
        "red": 3,
        "purple": 4,
        "yellow": 1
    },
    {
        "blue": 1,
        "red": 2,
        "purple": 4,
        "yellow": 3
    },
    {
        "blue": 3,
        "red": 4,
        "purple": 2,
        "yellow": 1
    }
];

const empty_obj = {
    "blue": 0,
    "red": 0,
    "purple": 0,
    "yellow": 0
}
result = results.reduce( reducer , empty_obj)
console.log( result )

function reducer( acc, val ) {
  for( key in val )
    if( val[key] === 1 ) acc[key]++;

  return acc;
}

于 2021-06-07T16:55:17.290 回答