如何使用json对象上的每个排列组合创建json对象数组

时间:2019-01-23 15:24:10

标签: javascript node.js json

我有一个下面的json对象,它是一些键值对,其中value是一个数组。

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

现在,我想解析此JSON并从中生成一个JSON数组,如下所示,其中每个数组都是JSON中每个值的PNC ...

{
    "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"
        }
    ]
}

3 个答案:

答案 0 :(得分:1)

如果具有对象的数组再次调用getCartesian并构建新的对象,则可以采用递归函数来分离所有键/值对,并通过迭代值来构建新的笛卡尔积。

这同样适用于嵌套对象。

该算法非常简单,因为它采用具有值的任何属性,而不是数组或对象,并保留该值并迭代数组或对象的所有其他属性。该算法保留了内部结构,仅将原始值作为给定结构的结果值。

一开始,它需要一个对象/数组,获取所有条目,并使用带有空对象的数组对其进行迭代。

空数组temp是新结果。

为创建新元素,迭代累加器r并收集新值。这是第一级笛卡尔乘积的组成部分。

对于更深层次的内容,将检查值,如果是对象,则进行递归调用,并为实际键获取新结果。

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; }

答案 1 :(得分:0)

这是一个可行的方法,但也许是缓慢的解决方案:

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)

答案 2 :(得分:0)

首先,您想将eachBook初始化为一个空数组 var eachBook = [];

然后,您要迭代每本书,书名,作者和出版商,并为每本书添加组合到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]
        });
      }
    }
  }
}