1

I have a json object as below which is a having some key value pairs where value is an array..

{
    "bookSet": {
        "book": ["book1", "book2", "book3"],
        "title": ["title1", "title2"],
        "author": ["author1"],
        "publisher": ["publisher1"]
    }
}

Now i want to parse this JSON and generate a JSON array out of this as below where each array is a PNC of each values in above json...

{
    "eachBook": [{
            "book": "book1",
            "title": "title1",
            "author": "author1",
            "publisher": "publisher1"
        },
        {
            "book": "book2",
            "title": "title1",
            "author": "author1",
            "publisher": "publisher1"
        }, {
            "book": "book3",
            "title": "title1",
            "author": "author1",
            "publisher": "publisher1"
        }, {
            "book": "book1",
            "title": "title2",
            "author": "author1",
            "publisher": "publisher1"
        }, {
            "book": "book2",
            "title": "title2",
            "author": "author1",
            "publisher": "publisher1"
        }, {
            "book": "book3",
            "title": "title2",
            "author": "author1",
            "publisher": "publisher1"
        }
    ]
}
Lucifer007
  • 107
  • 1
  • 14

3 Answers3

2

You could take a recursive function which separates all key/value pairs and build a new cartesian product by iterating the values, if an array with objects call getCartesian again and build new objects.

This works for nested objects as well.

The algorithm is pretty simple, because it take any property with a value, not an array or object and keeps this value and iterates all other properies who are arrays or objects. This algorithm keeps the inner structure and takes only the primitive values as result value for the given structure.

At the beginning, it takes an object/array, gets all entries and iterates them by using an array with an empty object.

An empty array temp is the new result.

For creating new elements, the accumulator r is iterated and new values are collected. this is the part where a first level of a cartesian product is made.

For a deeper level, a value is checked and if an object, then a recursive call is made and the new result is taken for the actual key.

function getCartesian(object) {
    return Object.entries(object).reduce((r, [k, v]) => {
        var temp = [];
        r.forEach(s =>
            (Array.isArray(v) ? v : [v]).forEach(w =>
                (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                    temp.push(Object.assign({}, s, { [k]: x }))
                )
            )
        );
        return temp;
    }, [{}]);
}

var input = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } },
    cartesian = { eachBook: getCartesian(input.bookSet) };

console.log(cartesian);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Here's a working, but maybe slow solution:

var output={
      "eachBook":[]
    },
    json={
        "bookSet": {
            "book": ["book1", "book2", "book3"],
            "title": ["title1", "title2"],
            "author": ["author1"],
            "publisher": ["publisher1"]
        }
    };
for(book of json.bookSet.book){
  for(title of json.bookSet.title){
    for(author of json.bookSet.author){
      for(publisher of json.bookSet.publisher){
        output.eachBook.push({
            "book": book,
            "title": title,
            "author": author,
            "publisher": publisher
        })
      }
    }
  }
}

console.log(output)
FZs
  • 16,581
  • 13
  • 41
  • 50
0

First you want to initialize eachBook as an empty array var eachBook = [];

Then you want to iterate each book, title, author, and publisher, and for each one add the combination to eachBook.

for(var i in bookSet.book) {
  for(var j in bookSet.title) {
    for(var k in bookSet.author) {
      for(var l in bookSet.publisher) {
        eachBook.push({
          book: bookSet.book[i],
          title: bookSet.title[j],
          author: bookSet.author[k],
          publisher: bookSet.publisher[l]
        });
      }
    }
  }
}
pmar
  • 314
  • 1
  • 6
  • [Why is using “for…in” with array iteration a bad idea?](https://stackoverflow.com/q/500504/8376184) – FZs Jan 23 '19 at 15:36