посчитать все значения в массиве объектов - JavaScript - PullRequest
2 голосов
/ 21 марта 2019

Мне нужно подсчитать каждое значение в массиве объектов, желаемый результат должен быть как ниже

[{
    "question": "question1",
    "USA": 2
  }, {
    "question": "question1",
    "AUS": 1
  },

  {
    "question": "question2",
    "item1": 2
  },

  {
    "question": "question2",
    "item1,item2": 1
  }, {
    "question": "question4",
    "3": 1
  }, {
    "question": "question4",
    "2": 1
  }
]

Ниже приведен вход, который мне нужно преобразовать в вышеприведенный вывод. Я понятия не имею, как это сделать без вопросов, а также получил проблему, когда один вопрос имеет 2 ответа. пример ввода

[{"question1":"USA","question2":["item1"],"question4":2}, 
{"question1":"USA","question2":["item1"],"question4":3}, 
{"question1":"AUS","question2":["item1","item2"]}];

let arr=[{"question1":"USA","question2":["item1"],"question4":2},{"question1":"USA","question2":["item1"],"question4":3},{"question1":"AUS","question2":["item1","item2"]}];
//console.log(arr);



function solve(list){
    var map = new Map();
    var entry = null;
    for(var item of list){
        if(!map.has(item.question1))
            map.set(item.question1, {question:'question1'});

            entry = map.get(item.question1);

        if(entry.hasOwnProperty(item.question1))
            entry[item.question1] = entry[item.question1] + 1;
        else
            entry[item.question1] = 1;
            
         
          if(!map.has(item.question2))
            map.set(item.question2, {question: 'question2'});

            entry = map.get(item.question2);

        if(entry.hasOwnProperty(item.question2))
            entry[item.question2] = entry[item.question2] + 1;
        else
            entry[item.question2] = 1;
         
    }
    return Array.from(map.values());
}
console.log(solve(arr))

Ответы [ 3 ]

3 голосов
/ 21 марта 2019

Вы можете взять объект или любую другую структуру данных, которая вам нравится, которая поддерживает структуру ключ / значение во вложенном стиле, и собрать сначала все элементы, а затем воспроизвести собранное дерево.

Этот подход использует объекты, потому чтоключи являются строками, это важно для массива в качестве ключа.Это совместно с запятой, которая достаточна для этого варианта использования.

var data = [{ question1: "USA", question2: ["item1"], question4: 2 }, { question1: "USA", question2: ["item1"], question4: 3 }, { question1: "AUS", question2: ["item1", "item2"] }],
    hash = data.reduce((hash, o) => {
        Object.entries(o).forEach(([question, value]) => {
            var sub = hash[question] = hash[question] || Object.create(null);
            sub[value] = sub[value] || { question, [value]: 0 };
            sub[value][value]++;
        });
        return hash;
    }, Object.create(null)),
    result = Object.values(hash).reduce((r, sub) => [...r, ...Object.values(sub)], []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 21 марта 2019

Это вопрос суммирования ввода с использованием словаря (например, объекта) и отслеживания дубликатов.«Имя» пары имя / значение может быть однозначно идентифицировано путем объединения вопроса и ответа с некоторым разделителем.

const input = [{
    "question1": "USA",
    "question2": ["item1"],
    "question4": 2
  },
  {
    "question1": "USA",
    "question2": ["item1"],
    "question4": 3
  },
  {
    "question1": "AUS",
    "question2": ["item1", "item2"]
  }
];



//Sum the input to an array which we can easily search for duplciates
var repeatCounter = {};

input.forEach(objItem => {

  Object.keys(objItem).forEach(propItem => {


    //Get the counter and the string
    var s = `${propItem}-${objItem[propItem]}`;
    var c = repeatCounter[s] || 0;

    //Modify it or introduce it if absent
    repeatCounter[s] = c + 1;


  })

})




var output = Object.keys(repeatCounter).map(element => {

  var ret = {'question': element.split('-')[0]}

  ret[element.split('-')[1]] = repeatCounter[element];
  
  return ret;

})


   console.log(output);
.as-console-wrapper {
  max-height: 100% !important;
}

Тонкие корректировки, такие как укрепление разделителя, преобразование нескольких строк в элементы массива (как показано в вопросе), должны быть выполнены на практических основаниях.

1 голос
/ 21 марта 2019

Сначала получите страны, используя reduce.Затем используйте остальные вложенные циклы forEach:

const input = [{"question1":"USA","question2":["item1"],"question4":2}, 
{"question1":"USA","question2":["item1"],"question4":3}, 
{"question1":"AUS","question2":["item1","item2"]}];
const countriesOutput = input.reduce((acc, curr) => {
  if (!acc.some(e => e[curr.question1])) {
    acc.push({ question: "question1", [curr.question1]: 1 });
  } else {
    acc.find(e => e[curr.question1])[curr.question1]++;
  }
  return acc;
}, []);
let questionsOutput = [];
input.forEach(item => {
  Object.keys(item).forEach(key => {
    if (key != "question1") {
      if (Array.isArray(item[key])) {
        questionsOutput.push({ question: key, [item[key].join(",")]: 1 });
      } else {
        questionsOutput.push({ question: key, [item[key]]: 1 });
      }
    }
  });
});
const finalOutput = [...countriesOutput, ...questionsOutput];
console.log(finalOutput);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...