【问题标题】:How to group object properties by there pattern structure?如何通过那里的模式结构对对象属性进行分组?
【发布时间】:2021-07-20 23:42:18
【问题描述】:

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

我有这样的数据结构:

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_feesinitial_fees

其他字段根据 key 上的最后一个数字放在同一个对象中,可以将其视为 index 区分符。

【问题讨论】:

  • 我知道你在使用 react,但是你的问题与 reactjs...
  • 因为这个标签(reactjs),我几乎忽略了你的问题......删除不必要的(reactjsecmascript-6)标签,
  • @Nur 感谢您抽出宝贵时间提供帮助,是的,我正在删除 react 标签
  • @Nur 是的,目前正在通过它...

标签: javascript algorithm data-structures


【解决方案1】:

您必须先初始化父级(some_feesinitial_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);

【讨论】:

  • 这令人印象深刻,由于使用了for (const key in item) {,我收到此错误The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype,您是否有替代解决方案以及最后一个问题...您将如何删除_number解决方案的每个键?
  • 是语法错误吗?并解释你的数据结构的模式......
  • 如何为解决方案的每个键删除 _number?我不明白你的问题,请解释
  • 我认为它与这篇文章有关https://stackoverflow.com/questions/1963102/what-does-the-jslint-error-body-of-a-for-in-should-be-wrapped-in-an-if-statemen 答案是First of all, never use a for in loop to enumerate over an array. The reason behind this is the following: each object in JavaScript has a special field called prototype.
  • 当然,您看到您提供的解决方案中的所有字段了吗?我希望他们以initial_fees_type: "random", 为例,而不是initial_fees_type_2: "random",。发生的事情是我删除了后缀_2。我想要他们所有人都一样。
【解决方案2】:

我想知道这种事情是否有某种更通用的解决方案。 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, k1, k2, 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));

【讨论】:

    猜你喜欢
    • 2016-04-30
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多