创建JSON对象的排列?

时间:2018-08-19 01:26:54

标签: javascript python json recursion

如果我得到这样的输入:

[
    {
        "name":     "Robert",
        "city": "New York",
        "short":  "Bob"
    },
    {
        "name":     "Allison",
        "city": "Los Angeles",
        "short":  "Ally"
    },
    {
        "name":     "James",
        "city": "Chicago",
        "short":  "Jim"
    },
    {
        "name": "Hannah",
        "city":"Toronto",
    },
    {
        "name": "Elizabeth",
        "city": "London",
    }
]

我将如何生成这样的输出,并在其中获得所有可能的组合?

[
    {"Robert": "New York", "Allison": "Los Angeles", "James": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Bob": "New York", "Allison": "Los Angeles", "James": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Robert": "New York", "Ally": "Los Angeles", "James": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Bob": "New York", "Ally": "Los Angeles", "James": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Robert": "New York", "Allison": "Los Angeles", "Jim": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Bob": "New York", "Allison": "Los Angeles", "Jim": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Robert": "New York", "Ally": "Los Angeles", "Jim": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
    {"Bob": "New York", "Ally": "Los Angeles", "Jim": "Chicago", "Hannah": "Toronto", "Elizabeth": "London"},
]

StackOverflow系列,请提供帮助。

3 个答案:

答案 0 :(得分:2)

我认为您要寻找的是获取每个人可获得的每个可能的名称-城市对的笛卡尔乘积,而不是组合。即这些列表的笛卡尔乘积:

[('Robert', 'New York'), ('Bob', 'New York')]
[('Allison', 'Los Angeles'), ('Ally', 'Los Angeles')]
[('James', 'Chicago'), ('Jim', 'Chicago')]
[('Hannah', 'Toronto')]
[('Elizabeth', 'London')]

您需要做的第一件事是将一个人的名字-城市-短字典变成一个名字-城市/短-城市对列表的函数:

def pairs(person):
    names = [(person['name'], person['city'])]
    try:
        names.append((person['short'], person['city']))
    except KeyError:
        pass
    return names

现在,您需要使用map或理解力将此方法应用于所有人:

allpairs = map(pairs, people)

现在您可以通过以下方式致电产品

results = itertools.product(*allpairs)

现在您只需要将每个配对对转换为字典:

output = [dict(result) for result in results]

然后,您必须编写代码以将它们按所需的奇怪顺序放置(也许您只是想反向生产它们,然后将其反转?),并以看起来有点像的格式输出Python dict repr或JSON对象,但实际上两者都不是。 (此外,如果每个字典的顺序很重要,并且您没有使用Python 3.7或更高版本,则需要使用collections.OrderedDict而不是dict。)

答案 1 :(得分:0)

实际上,这是唯一的解决方案,它使用内置功能combinations。但是,它确实假定输入是有效的JSON。

[ map([ {(.name):.city},
        (if .short then {(.short):.city} else empty end) ] )
  | combinations
  | add ]

输出

[
  {
    "Robert": "New York",
    "Allison": "Los Angeles",
    "James": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Robert": "New York",
    "Allison": "Los Angeles",
    "Jim": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Robert": "New York",
    "Ally": "Los Angeles",
    "James": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Robert": "New York",
    "Ally": "Los Angeles",
    "Jim": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Bob": "New York",
    "Allison": "Los Angeles",
    "James": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Bob": "New York",
    "Allison": "Los Angeles",
    "Jim": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Bob": "New York",
    "Ally": "Los Angeles",
    "James": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  },
  {
    "Bob": "New York",
    "Ally": "Los Angeles",
    "Jim": "Chicago",
    "Hannah": "Toronto",
    "Elizabeth": "London"
  }
]

答案 2 :(得分:0)

如果您正在寻找Javascript解决方案,则需要自己的笛卡尔积函数,但其​​余部分与上述Python解决方案非常相似。这个函数使用了我周围的可变方笛卡尔函数,因此需要额外的步骤 C1 C2 C3 C4 C5 C6 H1 H2 H3 H4 H5 H6 NP_000005 P01023 Protein Name 8.57345 8.45938 8.68941 8.35913 8.48177 8.44560 8.40986 8.59392 8.46562 8.07999 8.22759 8.41817 NP_000010 P24752 Protein Name 8.32595 8.19273 8.10708 8.48156 7.99014 8.24859 8.78216 8.59592 8.48299 8.52647 8.34797 8.38534 。除此之外,它应该很简单:

cartesian.apply(null, arr)