0

I have this JSON:

var books = [

    { author: "George Owell", title: "1984", price: 0, page: 328}, 
    { author: "Jane Austen", title: "Pride And Prejudice", price: 20, page: 279}, 
    { author: "J.K. Rowling", title: "Harry Potter and the Sorcerer's Stone", price: 23, page: 320}, 
    { author: "Plato", title: "Apology", price: 0, page: 127}, 
    { author: "Sigmund Freud", title: "The Interpretation of Dreams"},
    { author: "George Owell", title: "Animal Farm", price: 0, page: 100}, 
    { author: "George Owell", title: "Omh", price: 0, page: 100}, 
    { author: "Plato", title: "Aristotle", price: 0, page: 227}

];

Now I want to make a table that outputs author and title. If the author is the same, title will be merged together. For example, "George Owell" will have title "1984, Animal Farm, Ohm.", "Plato" will have "Apology, Aristotle", and so on. How can I do it with jQuery or vanilla JavaScript?

RonyLoud
  • 2,408
  • 2
  • 20
  • 25
Raw Ro
  • 11
  • 1
    There's no JSON in your question: you have an array of objects. Anyway, I would probably use the array `.reduce()` method for this. Are you asking about how to produce HTML output to display the results, or just about how to merge the titles? The merging part can be done (more or less) the same way as in this question: http://stackoverflow.com/questions/33850412/merge-javascript-objects-in-array-with-same-key – nnnnnn May 18 '17 at 03:32
  • I can write the code really quickly to do this, if you don't care about the "price" or the "page" - these are "books" so want to create a new object called "authors" then I guess it would make sense... but I am thinking that you might be trying to solve another problem the wrong way. – Tim May 18 '17 at 03:42

4 Answers4

1

var books = [
    { author: "George Owell", title: "1984", price: 0, page: 328}, 
    { author: "Jane Austen", title: "Pride And Prejudice", price: 20, page: 279}, 
    { author: "J.K. Rowling", title: "Harry Potter and the Sorcerer's Stone", price: 23, page: 320}, 
    { author: "Plato", title: "Apology", price: 0, page: 127}, 
    { author: "Sigmund Freud", title: "The Interpretation of Dreams"},
    { author: "George Owell", title: "Animal Farm", price: 0, page: 100}, 
    { author: "George Owell", title: "Omh", price: 0, page: 100}, 
    { author: "Plato", title: "Aristotle", price: 0, page: 227}
];

var uniqueauthors = [];
$.each(books,function(index,value){
if($.inArray(value.author,uniqueauthors) < 0)
{
uniqueauthors.push(value.author);
}
});

$.each(uniqueauthors,function(index,value){
var bok = $.map(books,function(val,index){
return (val.author == value) ? val.title : null;
});
var $tr = $('<tr>').append('<td>'+value+'</td>').append('<td>'+bok.join(",")+'</td>');
$('table').append($tr);
});
td{
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Authors</td>
<td>Titles</td>
</tr>
</table>
RonyLoud
  • 2,408
  • 2
  • 20
  • 25
0

Something like the following should get you started:

var books = [

    { author: "George Owell", title: "1984", price: 0, page: 328}, 
    { author: "Jane Austen", title: "Pride And Prejudice", price: 20, page: 279}, 
    { author: "J.K. Rowling", title: "Harry Potter and the Sorcerer's Stone", price: 23, page: 320}, 
    { author: "Plato", title: "Apology", price: 0, page: 127}, 
    { author: "Sigmund Freud", title: "The Interpretation of Dreams"},
    { author: "George Owell", title: "Animal Farm", price: 0, page: 100}, 
    { author: "George Owell", title: "Omh", price: 0, page: 100}, 
    { author: "Plato", title: "Aristotle", price: 0, page: 227}
    ];


   var authorBooks = {}

   books.forEach(function(book) {

      if(!authorBooks[book.author]) {
        authorBooks[book.author] = [];
      }

      authorBooks[book.author].push({title: book.title, price: book.price, page: book.page});

    },{});
Beamer180
  • 1,501
  • 5
  • 19
  • 25
0

Same question popped up yesterday in python. Here's my answer: https://stackoverflow.com/a/44017627/7633845

Here's a js version:

var map = {}
for(var i = 0; i < books.length; i++) {
    var book = books[i];
    if(!(book.author in map)) {
        map[book.author] = []
    }
    map[book.author].push(book.title)
}

var out = []
for(var author in map) {
    out.push({
        author: author,
        books: map[author].join(", ")
    })
}
Community
  • 1
  • 1
ハセン
  • 377
  • 3
  • 5
0

you can try

var books = [

{ author: "George Owell", title: "1984", price: 0, page: 328}, 
{ author: "Jane Austen", title: "Pride And Prejudice", price: 20, page: 279}, 
{ author: "J.K. Rowling", title: "Harry Potter and the Sorcerer's Stone", price: 23, page: 320}, 
{ author: "Plato", title: "Apology", price: 0, page: 127}, 
{ author: "Sigmund Freud", title: "The Interpretation of Dreams"},
{ author: "George Owell", title: "Animal Farm", price: 0, page: 100}, 
{ author: "George Owell", title: "Omh", price: 0, page: 100}, 
{ author: "Plato", title: "Aristotle", price: 0, page: 227}
];

var results = books.reduce((previous, book) => {
(previous[book.author] = previous[book.author] || []).push(book);
    return previous;
}, []);

console.log(results);
Nair Athul
  • 823
  • 9
  • 21