使用纯JavaScript展平嵌套对象的部分。

huangapple go评论66阅读模式
英文:

Flatten part of nested object using vanilla javascript

问题

{
  "units": [
    {
        "UnitName": "Unit1",
        "UnitID": 1,
        "depts": [
          {"DeptName": "Dept1-1"}
        ]
    },
    {
        "UnitName": "Unit2",
        "UnitID": 2,
        "depts": [
          {"DeptName": "Dept2-1"},
          {"DeptName": "Dept2-2"}
        ]
    }
  ]
}
英文:

I am using a library that returns a filtered version of results. The problem is that the results add an additional "item" layer for each object that is in an array which is not the format I need. Note below how both units and depts are wrapped in the "ITEM":{} object. I want to remove that item layer using just vanilla javascript.

{
  "units": [
    {
      "ITEM": {
        "UnitName": "Unit1",
        "UnitID": 1,
        "depts": [
          {"ITEM": {"DeptName": "Dept1-1"}}
        ]
      }
    },
    {
      "ITEM": {
        "UnitName": "Unit2",
        "UnitID": 2,
        "depts": [
          {"ITEM": {"DeptName": "Dept2-1"}},
          {"ITEM": { "DeptName": "Dept2-2"}}
        ]
      }
    }
  ]
}

I would like to partially flatten this so it looks like the following.

{
  "units": [
    {
        "UnitName": "Unit1",
        "UnitID": 1,
        "depts": [
          {"DeptName": "Dept1-1"}
        ]
    },
    {
        "UnitName": "Unit2",
        "UnitID": 2,
        "depts": [
          {"DeptName": "Dept2-1"},
          { "DeptName": "Dept2-2"}
        ]
    }
  ]
}

Because I will be repeating this for other data, I'm trying to figure out a generic function to remove this extra layer whenever there is an "item" object wrapped around every returned object in an array.
However, every example I can find to flatten a javascript object assumes I want the entire thing flattened. Example 1, Example 2

I'm sure there has got to be an existing solution already, but I probably need to use another word other than flattening to find the right results. Help would be greatly appreciated!

答案1

得分: 0

你可以使用 Object.assign 和 map 在数组上实现这一点:

data = Object.assign(data, {
  "units": data.units
    .map((u) => Object.assign(u.ITEM, {
      "depts": u.ITEM.depts
        .map((d) => d.ITEM)
    }))
});
英文:

You can use Object.assign and map on array to achieve that:

data = Object.assign(data, {
  "units": data.units
    .map((u) => Object.assign(u.ITEM, {
       "depts": u.ITEM.depts
         .map((d) => d.ITEM) 
    }))
});

答案2

得分: 0

你可以递归地遍历对象树并清理:

// 遍历对象树并用 `???` 替换 `{ ITEM: ??? }`
function removeITEM(item) {
  if (typeof item !== "object" || item === null) return item;

  if (Array.isArray(item)) return item.map(removeITEM);

  // 清理发生的地方
  if (item.ITEM) return removeITEM(item.ITEM);

  let copy = {};
  for (let key in item) {
    copy[key] = removeITEM(item[key]);
  }
  return copy;
}

console.log(removeITEM({
  "units": [
    {
      "ITEM": {
        "UnitName": "Unit1",
        "UnitID": 1,
        "depts": [
          { "ITEM": { "DeptName": "Dept1-1" } }
        ]
      }
    },
    {
      "ITEM": {
        "UnitName": "Unit2",
        "UnitID": 2,
        "depts": [
          { "ITEM": { "DeptName": "Dept2-1" } },
          { "ITEM": { "DeptName": "Dept2-2" } }
        ]
      }
    }
  ]
}));

或者另一种选择:如果你可以访问 JSON 字符串(比如来自 AJAX 请求),可以在 JSON.parse() 上清理数据结构:

const json = '{"units":[{"ITEM":{"UnitName":"Unit1","UnitID":1,"depts":[{"ITEM":{"DeptName":"Dept1-1"}}]}},{"ITEM":{"UnitName":"Unit2","UnitID":2,"depts":[{"ITEM":{"DeptName":"Dept2-1"}},{"ITEM":{"DeptName":"Dept2-2"}}]}}]}';

console.log(JSON.parse(json, (key, value) => (value && value.ITEM) ?? value));
英文:

you can recursively traverse the object tree and clean up:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// traverses the object tree and replaces `{ ITEM: ??? }` with the `???`
function removeITEM(item) {
  if (typeof item !== &quot;object&quot; || item === null) return item;

  if (Array.isArray(item)) return item.map(removeITEM);

  // that&#39;s where the cleanup happens
  if (item.ITEM) return removeITEM(item.ITEM);

  let copy = {};
  for (let key in item) {
    copy[key] = removeITEM(item[key]);
  }
  return copy;
}

console.log(removeITEM({
  &quot;units&quot;: [
    {
      &quot;ITEM&quot;: {
        &quot;UnitName&quot;: &quot;Unit1&quot;,
        &quot;UnitID&quot;: 1,
        &quot;depts&quot;: [
          { &quot;ITEM&quot;: { &quot;DeptName&quot;: &quot;Dept1-1&quot; } }
        ]
      }
    },
    {
      &quot;ITEM&quot;: {
        &quot;UnitName&quot;: &quot;Unit2&quot;,
        &quot;UnitID&quot;: 2,
        &quot;depts&quot;: [
          { &quot;ITEM&quot;: { &quot;DeptName&quot;: &quot;Dept2-1&quot; } },
          { &quot;ITEM&quot;: { &quot;DeptName&quot;: &quot;Dept2-2&quot; } }
        ]
      }
    }
  ]
}));

<!-- language: lang-css -->

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

<!-- end snippet -->

Or maybe an alternative: If you have access to the JSON string (like from a ajax request) it may be an option to clean the data structure up on JSON.parse():

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const json = &#39;{&quot;units&quot;:[{&quot;ITEM&quot;:{&quot;UnitName&quot;:&quot;Unit1&quot;,&quot;UnitID&quot;:1,&quot;depts&quot;:[{&quot;ITEM&quot;:{&quot;DeptName&quot;:&quot;Dept1-1&quot;}}]}},{&quot;ITEM&quot;:{&quot;UnitName&quot;:&quot;Unit2&quot;,&quot;UnitID&quot;:2,&quot;depts&quot;:[{&quot;ITEM&quot;:{&quot;DeptName&quot;:&quot;Dept2-1&quot;}},{&quot;ITEM&quot;:{&quot;DeptName&quot;:&quot;Dept2-2&quot;}}]}}]}&#39;;

console.log(JSON.parse(json, (key, value) =&gt; (value &amp;&amp; value.ITEM) ?? value));

<!-- language: lang-css -->

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

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月27日 07:04:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定