收集深层嵌套数据的平面数组

时间:2018-05-30 21:31:24

标签: javascript arrays

我有字典:

var objectSchemasList = {
  1: [
    {
        name: 'list_field1_1',
      uuid: 'uuid1',
      fieldObjectSchemaId: 2
    },
    {
        name: 'list_field1_2',
      uuid: 'uuid2',
      fieldObjectSchemaId: null
    },
  ],
  2: [
    {
        name: 'list_field2_1',
      uuid: 'uuid3',
      fieldObjectSchemaId: null
    },
    {
        name: 'list_field2_2',
      uuid: 'uuid4',
      fieldObjectSchemaId: null
    },
  ],
  3: [
    {
        name: 'list_field3_1',
      uuid: 'uuid5',
      fieldObjectSchemaId: 1
    },
    {
        name: 'list_field3_2',
      uuid: 'uuid6',
      fieldObjectSchemaId: null
    },
  ],
}

以及与之相关的一系列数据:

const objectSchemaFields = [
    {
    name: 'field_1',
    uuid: '_uuid1',
    fieldObjectSchemaId: null
  },
  {
    name: 'field_2',
    uuid: '_uuid2',
    fieldObjectSchemaId: null
  },
  {
    name: 'field_3',
    uuid: '_uuid3',
    fieldObjectSchemaId: 1
  },
];

这意味着每个对象架构字段都可以包含其他字段。这是由fieldObjectSchemaId链接的。这意味着objectSchemaFields[2]元素使用objectSchemasList[objectSchemaFields[2].fieldObjectSchemaId]。这也使用objectSchemasList[2]等等。它可以无限嵌套。我想从这个结构得到平面阵列。我在这里tried。最终数组应该是平的,只有path, name, uuid属性。其中path包含父名称和由point分割的所有嵌套子名称的串联。例如,结果应为:

const result = [
  {
    path: 'field_1',
    name: 'field_1',
    uuid: '_uuid1',
    },
  {
    path: 'field_2',
        name: 'field_2',
    uuid: '_uuid2',
    },
  {
    path: 'field_3',
    name: 'field_3',
    uuid: '_uuid3',
  },
  {
    path: 'field_3.list_field1_1',
    name: 'list_field1_1',
    uuid: 'uuid1',
  },
  {
    path: 'field_3.list_field1_1.list_field2_1',
    name: 'list_field2_1',
    uuid: 'uuid3',
  },
  {
    path: 'field_3.list_field1_1.list_field2_2',
    name: 'list_field2_2',
    uuid: 'uuid4',
  },
  {
    path: 'field_3.list_field1_2',
    name: 'list_field1_2',
    uuid: 'uuid2',
    }
]

2 个答案:

答案 0 :(得分:1)

这不是一个很好的地图用例,因为您仍然需要将原始对象与子对象一起返回,然后您需要将其展平。最好坚持使用普通的旧数组变量,或者如果你想要花哨的话,可以使用reduce

var output = [];

function processObject(path, obj) {
  path = path.concat([obj.name]);
  output.push({
    path: path.join("."),
    name: obj.name,
    uuid: obj.uuid,
  });
  var schema = objectSchemasList[obj.fieldObjectSchemaId];
  if (schema) {
    schema.forEach(processObject.bind(null, path));
  }
}

objectSchemaFields.forEach(processObject.bind(null, []));

https://jsfiddle.net/m8t54bv5/

答案 1 :(得分:1)

您可以通过递归调用展平函数来减少数组。



function flat(p) {
    return function (r, { name, uuid, fieldObjectSchemaId }) {
        var path = p + (p && '.') + name;
        r.push({ path, name, uuid });
        return (objectSchemasList[fieldObjectSchemaId] || []).reduce(flat(path), r);
    };
}

var objectSchemasList = { 1: [{ name: 'list_field1_1', uuid: 'uuid1', fieldObjectSchemaId: 2 }, { name: 'list_field1_2', uuid: 'uuid2', fieldObjectSchemaId: null }], 2: [{ name: 'list_field2_1', uuid: 'uuid3', fieldObjectSchemaId: null }, { name: 'list_field2_2', uuid: 'uuid4', fieldObjectSchemaId: null }], 3: [{ name: 'list_field3_1', uuid: 'uuid5', fieldObjectSchemaId: 1 }, { name: 'list_field3_2', uuid: 'uuid6', fieldObjectSchemaId: null }] },
    objectSchemaFields = [{ name: 'field_1', uuid: '_uuid1', fieldObjectSchemaId: null }, { name: 'field_2', uuid: '_uuid2', fieldObjectSchemaId: null }, { name: 'field_3', uuid: '_uuid3', fieldObjectSchemaId: 1 }],
    result = objectSchemaFields.reduce(flat(''), []);

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }