admin管理员组

文章数量:1290927

So I've been stumped on this for hours and I can't really figure out an elegant solution to solve this problem. Let's say I have an array like this:

[
   {
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
{
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
   {
     question: "What is dog's name?",
     answer: "Snugglets",
     topic: "names"
   },
   {
     question: "What is your brother's age?",
     answer: 55,
     topic: "ages"
   }
]

How can I turn this into an array that looks like this?

[
   {
     topic: "names",
     content: [...array of objects based on "names"...]
   },
{
     topic: "ages",
     content: [...array of objects based on "ages"...]
   }
]

I feel this is something that should be really easy, but for some reason my brain cannot seem to grasp the solution. What am I missing here?

UPDATE: Thanks for all the responses! I was not expecting to get this many methods of acplishing this. I accepted one of the answers, as it was related to ES6 and I should have specified that I was looking to learn the ES6 way of doing this, if possible :)

Though, I must also say that the needs have also changed a bit where instead of the intended array, being like this:

[ { topic: "names", content: [...array of objects based on "names"...] }, { topic: "ages", content: [...array of objects based on "ages"...] } ]

The array needs to look like more like this:

[ { topic: "names", content: '<div> <h3>Question: What is your name?</h3> <p>Answer: Ben</p> </div> <div> <h3>Question: What is your dog's name?</h3> <p>Answer: Snugglets</p> </div>' }, { topic: "ages", content: content: '<div> <h3>Question: What is your age?</h3> <p>Answer: 50</p> </div> <div> <h3>Question: What is your brother's age?</h3> <p>Answer: 52</p> </div>' } ]

Normally I don't like to just ask for code given to me, but my Javascript foo seems to a bit weaker when it es to transforming data algorithmically :( Any thoughts on how I could merge all of those array elements into a single string, containing HTML, that serves as the "content" key of each "topic"?

Also, would this be better served in another question on Stackoverflow?

So I've been stumped on this for hours and I can't really figure out an elegant solution to solve this problem. Let's say I have an array like this:

[
   {
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
{
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
   {
     question: "What is dog's name?",
     answer: "Snugglets",
     topic: "names"
   },
   {
     question: "What is your brother's age?",
     answer: 55,
     topic: "ages"
   }
]

How can I turn this into an array that looks like this?

[
   {
     topic: "names",
     content: [...array of objects based on "names"...]
   },
{
     topic: "ages",
     content: [...array of objects based on "ages"...]
   }
]

I feel this is something that should be really easy, but for some reason my brain cannot seem to grasp the solution. What am I missing here?

UPDATE: Thanks for all the responses! I was not expecting to get this many methods of acplishing this. I accepted one of the answers, as it was related to ES6 and I should have specified that I was looking to learn the ES6 way of doing this, if possible :)

Though, I must also say that the needs have also changed a bit where instead of the intended array, being like this:

[ { topic: "names", content: [...array of objects based on "names"...] }, { topic: "ages", content: [...array of objects based on "ages"...] } ]

The array needs to look like more like this:

[ { topic: "names", content: '<div> <h3>Question: What is your name?</h3> <p>Answer: Ben</p> </div> <div> <h3>Question: What is your dog's name?</h3> <p>Answer: Snugglets</p> </div>' }, { topic: "ages", content: content: '<div> <h3>Question: What is your age?</h3> <p>Answer: 50</p> </div> <div> <h3>Question: What is your brother's age?</h3> <p>Answer: 52</p> </div>' } ]

Normally I don't like to just ask for code given to me, but my Javascript foo seems to a bit weaker when it es to transforming data algorithmically :( Any thoughts on how I could merge all of those array elements into a single string, containing HTML, that serves as the "content" key of each "topic"?

Also, would this be better served in another question on Stackoverflow?

Share Improve this question edited Jun 8, 2016 at 0:37 Stevie Star asked Jun 7, 2016 at 8:01 Stevie StarStevie Star 2,3712 gold badges34 silver badges60 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 3

You could group it with a temporary object and iterate over with Array#forEach.

The forEach() method executes a provided function once per array element.

var data = [{ question: "what is your name?", answer: "Ben", topic: "names" }, { question: "what is your name?", answer: "Ben", topic: "names" }, { question: "What is dog's name?", answer: "Snugglets", topic: "names" }, { question: "What is your brother's age?", answer: 55, topic: "ages" }],
    group = [];

data.forEach(function (a) {
    if (!this[a.topic]) {
        this[a.topic] = { topic: a.topic, content: [] };
        group.push(this[a.topic]);
    }
    this[a.topic].content.push(a);
}, Object.create(null));

console.log(group);

Can be simply done as follows when ES6 Map object is utilized. I also removed the redundant names property from the items of the content array.

var data = [{question: "what is your name?",answer: "Ben",topic: "names"},{question: "what is your name?",answer: "Ben",topic: "names"},{question: "What is dog's name?",answer: "Snugglets",topic: "names"},{question: "What is your brother's age?",answer: 55,topic: "ages"}],
 mapData = data.reduce((p,c) => p.has(c.topic) ? p.set(c.topic,p.get(c.topic).concat({question:c.question,
                                                                                        answer:c.answer}))
                                               : p.set(c.topic,[{question:c.question,
                                                                   answer:c.answer}]),new Map()),
  result = [...mapData].map(e => ({topic:e[0],content:e[1]}));
console.log(result);

A more functional approach is to use Array.reduce. This also removes the need for a temporary variable:

var output = data.reduce(function(prev, cur) {
  if (!prev[cur.topic]) prev[cur.topic] = [];
  prev[cur.topic].push(cur);
  return prev;
}, {});

See JS Bin for working example:
https://jsbin./yesucaquwa/1/edit?js,console

Try this:

var input = [
   {
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
{
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
   {
     question: "What is dog's name?",
     answer: "Snugglets",
     topic: "names"
   },
   {
     question: "What is your brother's age?",
     answer: 55,
     topic: "ages"
   }
];
var tmp = input.reduce(function(topics, obj) {
  topics[obj.topic] = topics[obj.topic] || {topic: obj.topic, content: []};
  topics[obj.topic].content.push(obj);
  return topics;
}, {});
var output = Object.keys(tmp).map(function(key) {
  return tmp[key];
});
console.log(output);

There is a simple function for you.

var arr=[
   {
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
    {
     question: "what is your name?",
     answer: "Ben",
     topic: "names"
   },
   {
     question: "What is dog's name?",
     answer: "Snugglets",
     topic: "names"
   },
   {
     question: "What is your brother's age?",
     answer: 55,
     topic: "ages"
   }
]
function turnToOtherArray(arr){
    var result=[];
    for(var i=0,mamorize={};i<arr.length;i++){
        if(mamorize[arr[i].topic]){
            mamorize[arr[i].topic].push(arr[i].question)
        }else{
            mamorize[arr[i].topic]=[arr[i].question]
        }
    }
    for(var key in mamorize){
        result[result.length] = { "topic" : key , "content" : mamorize[key]}
    }
    return result;
}
console.log(turnToOtherArray(arr));

本文标签: JavascriptHow to transform array list into another array list of key valuesStack Overflow