如何通过模式结构对对象属性进行分组?

问题描述

我有一种复杂的算法可以用 Javascript 编写。

我有这样的数据结构:

LinearLayout

我想实现这一目标:

const data = [
  {
    some_fees_dent_0: true,some_fees_name_0: "junao",some_fees_name_1: "adhm",some_fees_name_2: "uio",some_fees_rate_0: "45",some_fees_rate_1: "1",some_fees_rate_2: "22",some_fees: [],# HERE
    initial_fees: [],# HERE
    initial_fees_dent_0: true,initial_fees_name_0: "james",initial_fees_name_1: "daiep",initial_fees_name_2: "moaip",initial_fees_rate_0: "7",initial_fees_rate_1: "11",initial_fees_rate_2: "88",initial_fees_type_0: "foo",initial_fees_type_1: "bar",initial_fees_type_2: "random",}
]

基本上发生的事情是包含对象的初始 const data = [ { some_fees: [ { some_fees_name: "junao",# was initially some_fees_name_0 some_fees_rate: "45",# was initially some_fees_rate_0 some_fees_dent: true,# was initially some_fees_dent_0 },{ some_fees_name: "adhm",# was initially some_fees_name_1 some_fees_rate: "1",# was initially some_fees_rate_1 },{ some_fees_name: "uio",# was initially some_fees_name_2 some_fees_rate: "22",# was initially some_fees_rate_2 },],initial_fees: [ { initial_fees_name: "james",# was initially initial_fees_name_0 initial_fees_rate: "7",# was initially initial_fees_rate_0 initial_fees_type: "foo",# was initially initial_fees_type_0 initial_fees_dent: true,# was initially initial_fees_dent_0 },{ initial_fees_name: "daiep",# was initially initial_fees_name_1 initial_fees_rate: "11",# was initially initial_fees_rate_1 initial_fees_type: "bar",# was initially initial_fees_type_1 },{ initial_fees_name: "moaip",# was initially initial_fees_name_2 initial_fees_rate: "88",# was initially initial_fees_rate_2 initial_fees_type: "random",# was initially initial_fees_type_3 },} ] 数组现在只包含两个字段:data some_fees

其他字段根据其 initial_fees 上的最后一个数字放在同一个对象中,这可以被视为 key 微分器。

解决方法

您必须先初始化父级 (some_fees,initial_fees),然后按那里的模式将它们分组...

let data = [{ some_fees_dent_0: true,some_fees_name_0: "junao",some_fees_name_1: "adhm",some_fees_name_2: "uio",some_fees_rate_0: "45",some_fees_rate_1: "1",some_fees_rate_2: "22",some_fees: [],initial_fees: [],initial_fees_dent_0: true,initial_fees_name_0: "james",initial_fees_name_1: "daiep",initial_fees_name_2: "moaip",initial_fees_rate_0: "7",initial_fees_rate_1: "11",initial_fees_rate_2: "88",initial_fees_type_0: "foo",initial_fees_type_1: "bar",initial_fees_type_2: "random",}],groups = new Map,result = [];

for (let item of data) {
    let root = {},entries = Object.entries(item);
    result.push(root);

    for (let [key,value] of entries)
        if (Array.isArray(value))
            root[key] = []; // initializing parent node

    for (let [key,value] of entries) {
        let [k0,k1,k2,k3] = key.split('_'),modefiedKey = `${k0}_${k1}_${k2}`,groupID = `${k0}_${k1}_${k3}`,group = groups.get(groupID);

        if (!k2) continue;
        if (group) group[modefiedKey] = value;
        else {
            let node = { [modefiedKey]: value },parentNode = root[`${k0}_${k1}`];
            groups.set(groupID,node);
            if (parentNode) parentNode.push(node);
        }
    }
}
console.log(result);

,

我想知道是否可能有某种更通用的解决方案来解决此类问题。 create_object_from_structured_key_entries 的想法(可能会写得更好一些)是它将按照第一个 console.log() 中的示例获取带有“结构化”键的条目,然后创建一个对象适当的结构。对于您的数据,有一个 create_structured_key 函数可以将您的密钥转换为结构化密钥,以便它通过 create_object_from_structured_key_entries 运行。

const data = [{"some_fees_dent_0":true,"some_fees_name_0":"junao","some_fees_name_1":"adhm","some_fees_name_2":"uio","some_fees_rate_0":"45","some_fees_rate_1":"1","some_fees_rate_2":"22","some_fees":[],"initial_fees":[],"initial_fees_dent_0":true,"initial_fees_name_0":"james","initial_fees_name_1":"daiep","initial_fees_name_2":"moaip","initial_fees_rate_0":"7","initial_fees_rate_1":"11","initial_fees_rate_2":"88","initial_fees_type_0":"foo","initial_fees_type_1":"bar","initial_fees_type_2":"random"}];

const create_object_from_structured_key_entries = (entries) =>
  entries.reduce(
    (acc,[key,val]) => {
      let current_object = acc;
      const dot_parts = key.split('.');
      
      dot_parts.forEach((dot_part,i) => {
        const arr_parts = dot_part.replace(/]/g,'').split('[');
        const for_array = arr_parts.length > 1;
        const array_index = for_array ? +arr_parts[1] : null;
        
        if(!current_object[arr_parts[0]])
          current_object[arr_parts[0]] = for_array ? [] : {};
        
        if(for_array && !current_object[arr_parts[0]][array_index])
          current_object[arr_parts[0]][array_index] = {};
        
        if(i === dot_parts.length - 1) {
          if(for_array) {
            current_object[arr_parts[0]][array_index] = val;
          } else {
            current_object[arr_parts[0]] = val;
          }
          return;
        }
        
        if(for_array) {
          current_object = current_object[arr_parts[0]][array_index];
        } else {
          current_object = current_object[arr_parts[0]];
        }
      });
      
      return acc;
    },{}
  );

const create_structured_key = (key) => {
  const [k0,k3] = key.split('_');
  if(!k2) return null;
  return k0 + '_' + k1 + '[' + k3 + ']' + '.' + k0 + '_' + k1 + '_' + k2;
};

const data_item_to_structured_object = (item) =>
  create_object_from_structured_key_entries(
    Object.entries(item)
      .map(([key,val]) => [create_structured_key(key),val])
      .filter(([key,val]) => key)
  );
  
const data_to_structured_object = (arr) => arr.map(data_item_to_structured_object);

console.log(create_object_from_structured_key_entries( Object.entries({
  'a.aa[0].aaa[1]': 'bob','a.aa[0].ddd': 'fred','a.bb.eee': 'jane'
}) ));

console.log(data_to_structured_object(data));