【问题标题】:Flatten Array of Arrays That Contains Objects展平包含对象的数组
【发布时间】:2018-03-08 14:42:54
【问题描述】:

我遇到了扁平化数组的问题。

鉴于结构如下

{
  "name": "Somename",
  "property": [
    [
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      }
    ],
    [
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      }
    ],
    [
      {
        "prop": "someprop",
        "other": "someother"
      }
    ]
  ]
}

或者用这张图片更好地说明

如何将匹配项扁平化为单个对象数组或实际上具有扁平结构,其中所有嵌套项都在单个数组或对象中?

到目前为止,我已经设法通过整理数据取得了进展,但似乎卡在了这一点上,我几乎可以使用任何库或工具以及最新的 JS 功能。

我尝试过映射值,使用 lodash deepMerge 减少它,但似乎无法完成我想要的。

输入:

const data = [
       {
        "sport": "Handball",
        "matches": [
            [
                {
                    "home": "Izmir BSB SK (Youth) (Wom)",
                    "away": "Bursa Osmangazi (Youth) (Wom)",
                    "ID": "3092996854"
                }
            ],
            [
                {
                    "home": "Al Muheet U21",
                    "away": "Al Mohmel U21",
                    "ID": "3092999932"
                }
            ]
        ]
    },
    {
        "sport": "Volleyball",
        "matches": [
            [
                {
                    "home": "Ji-Hee Choi/Michika Ozeki",
                    "away": "Panji Ahmad Maulana",
                    "ID": "3093062401"
                },
                {
                    "home": "Ryazan (Wom)",
                    "away": "Angara Irkutsk (Wom)",
                    "ID": "3093062393"
                }
            ],
            [
                {
                    "home": "CF Carthage (Wom)",
                    "away": "Winner - Broughton Excels",
                    "ID": "3093721823"
                }
            ],
            [
                {
                    "home": "Ankara Yildirim Beyazit Universitesi (Wom)",
                    "away": "Saglik Bilimleri Universitesi (Wom)",
                    "ID": "3093058567"
                }
            ]
        ]
    }
    ]

每个匹配道具的预期输出:

    {
      "sport": "Handball",
      "matches": [
        {home: '...', other: '...', id: '...'},
        {home: '...', other: '...', id: '...'},
        {home: '...', other: '...', id: '...'},
        {home: '...', other: '...', id: '...'},
      ]
    }

【问题讨论】:

  • 您的预期输出是什么? [{.?.},{.?.}]
  • { "name": "Somename", "property": [ {prop: 'someProp', other: 'otherProp'}, {prop: 'someProp', other: 'otherProp'}, {prop:'someProp',其他:'otherProp'},{prop:'someProp',其他:'otherProp'}] }
  • 将其添加到您的问题中
  • Or maybe better illustrated with this pic - 不。我们讨厌图片;/
  • @georg 有照片吗?我看不到它们,.. :/ - 我想这就是为什么这可能适用,即使它本身不是代码Why not to upload Images of Code when asking a Question - 另外,谁知道该图像链接是否在 2 个月内仍然存在,使如果问题消失并且预期的输出不在问题中,则该问题对未来的用户毫无用处。

标签: javascript arrays object ecmascript-6 lodash


【解决方案1】:

您可以使用函数reduce 并使用函数Array.isArray 检查数组对象。

var data = {  "name": "Somename",  "property": [    [      {        "prop": "someprop",        "other": "someother"      },      {        "prop": "someprop",        "other": "someother"      }    ],    [      {        "prop": "someprop",        "other": "someother"      },      {        "prop": "someprop",        "other": "someother"      },      {        "prop": "someprop",        "other": "someother"      },      {        "prop": "someprop",        "other": "someother"      }    ],    [      {        "prop": "someprop",        "other": "someother"      }    ]  ]};

data.property = data.property.reduce((mapped, p) => 
                [...mapped, ...(Array.isArray(p) ? p : [p])], []);
//                                    ^
//                                    |
//                                    +- This is to check for situations where 
//                                       a particular object is not an array.

console.log(JSON.stringify(data, null, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢它实际上给了我一个我没有注意到的暗示。
【解决方案2】:

使用扩展运算符和array.concatarray.concat 有这个独特的条件,如果参数是一个数组,它会将那个数组的 contents 添加到结果数组而不是数组本身。展开运算符将数组的内容作为函数的 args 一个接一个地展开。

const flatProperties = [].concat(...data.property)

const data = {
  "name": "Somename",
  "property": [
    [
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      }
    ],
    [
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      }
    ],
    [
      {
        "prop": "someprop",
        "other": "someother"
      }
    ]
  ]
}

const flatProperties = [].concat(...data.property)

console.log(flatProperties)

【讨论】:

  • 是的,但是我有一组具有属性的对象,而这些属性又具有数组数组。我确实试过了。
  • 这个[].concat 是一种不好的做法。
【解决方案3】:

您可以在阵列上使用.reduce

data.property = data.property.reduce(
  (acc, el) => acc.concat(el) , []
)

var data = {
  "name": "Somename",
  "property": [
    [
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      }
    ],
    [
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      },
      {
        "prop": "someprop",
        "other": "someother"
      }
    ],
    [
      {
        "prop": "someprop",
        "other": "someother"
      }
    ]
  ]
};

data.property = data.property.reduce(
  (acc, el) => acc.concat(el) , []
)

console.log(data);

【讨论】:

    【解决方案4】:

    您可以使用concatapply 方法。这个答案类似于 Joseph 的答案,但没有 ES6 数组扩展运算符

    var originalArray = {
      "name": "Somename",
      "property": [
        [
          {
            "prop": "someprop",
            "other": "someother"
          },
          {
            "prop": "someprop",
            "other": "someother"
          }
        ],
        [
          {
            "prop": "someprop",
            "other": "someother"
          },
          {
            "prop": "someprop",
            "other": "someother"
          },
          {
            "prop": "someprop",
            "other": "someother"
          },
          {
            "prop": "someprop",
            "other": "someother"
          }
        ],
        [
          {
            "prop": "someprop",
            "other": "someother"
          }
        ]
      ]
    };
    
    var flattened = [].concat.apply([],originalArray["property"]);
    console.log(flattened)

    【讨论】:

      【解决方案5】:

      如果您使用的是 lodash,这也可以。

      var data = {
        "name": "Somename",
        "property": [
          [
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            }
          ],
          [
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            }
          ],
          [
            {
              "prop": "someprop",
              "other": "someother"
            }
          ]
        ]
      }
      
      data.property = _.flattenDeep(data.property)
      
      console.log(data);
      <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

      【讨论】:

      • 我必须映射原始数组并操作具有嵌套对象数组的属性,我也尝试过 lodash。
      【解决方案6】:

      可以使用递归函数遍历数组

      const props = {
        "name": "Somename",
        "property": [
          [
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            }
          ],
          [
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            },
            {
              "prop": "someprop",
              "other": "someother"
            }
          ],
          [
            {
              "prop": "someprop",
              "other": "someother"
            }
          ]
        ]
      };
      
      
      function smoosh(populate) {
          return function _smoosh(arr) {
              if ( Array.isArray(arr) ) {
                  for ( let value of arr ) {
                      _smoosh(value);
                  }
              }
              if ( typeof(arr) === "object" && ! Array.isArray(arr) ) {
                  populate.push(arr);
              }
          };
      }
      
      const flatten = [];
      
      smoosh(flatten)(props.property);
      
      Object.assign(props,{
          property: flatten
      });
      console.log(props);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-17
        • 2020-11-15
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        相关资源
        最近更新 更多