Voque
Voque

Reputation: 168

Recursivly removing unecessary nesting in array of objects

Here is sample array of objects:

const test = [
  {
    properties: {
      test1: "aa",
      test2: "bb",
      button: [
        {
          properties: {
            btnTest1: "aa",
            btnTest2: "bb"
          }
        }
      ]
    }
  },
  {
    properties: {
      test1: "aa",
      test2: "bb",
      button: [
        {
          properties: {
            btnTest1: "aa",
            btnTest2: "bb"
          }
        }
      ]
    },
  }
]

Using recursive function i want somehow to be able get rid of "properties" key so the result will be:

const test = [
  {
    test1: "aa",
    test2: "bb",
    button: [
      {
        btnTest1: "aa",
        btnTest2: "bb"
      }
    ]
  },
  {
     test1: "aa",
     test2: "bb",
     button: [
       {
         btnTest1: "aa",
         btnTest2: "bb"
       }
     ]
  }
]

I'm struggling to achive this and i don't really have any code that im working on to share here. Thanks to anyone who are willing to help.

Upvotes: 1

Views: 308

Answers (3)

Scott Sauyet
Scott Sauyet

Reputation: 50797

This approach is somewhat different from the other answers. First, it makes the property name to alter (here "properties") configurable. More importantly, this does not assume that "properties" (or whatever) is the only property of the object being modified. So

{
  foo: 42,
  properties: {bar: 'abc'}
}

would become

{
  foo: 42,
  bar: 'abc'
}

That feature may or may not be important to you, but it's an interesting alternative.

This does allow for some ambiguities. In this implementation, if a name is defined in the root and inside properties, the latter will overwrite the former. But that could be easily changed.

const flatProp = (p) => (o) => 
  Array .isArray (o)
    ? o .map (flatProp (p))
  : Object (o) === o
    ? Object .fromEntries (Object .entries (o) .flatMap (
        ([k, v]) =>  k === p 
          ? Object .entries (v) .map (([k, v]) => [k, flatProp(p)(v)]) 
          : [[k, v]]
      ))
  : o


const input = [{properties: {test1: "aa", test2: "bb", button: [{properties: {btnTest1: "aa", btnTest2: "bb"}}]}}, {properties: {test1: "aa", test2: "bb", button: [{properties: {btnTest1: "aa", btnTest2: "bb"}}]}}]

console .log (flatProp ('properties') (input))
.as-console-wrapper {max-height: 100% !important; top: 0}

Of course this curried function can be partially applied if you prefer:

const upgradeProperties = flatProp ('properties')

console .log (upgradeProperties (input))

If you are stuck in an environment without Object.fromEntries, it's quite easy to shim.

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386654

You could take various checks and create new objects without unwanted property.

function remove(value) {
    if (!value || typeof value !== 'object') return value;
    if (Array.isArray(value)) return value.map(remove);
    if ('properties' in value) return remove(value.properties);
    return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, remove(v)]));
}

const test = [{ properties: { test1: "aa", test2: "bb", button: [{ properties: { btnTest1: "aa", btnTest2: "bb" } }] }}, { properties: { test1: "aa", test2: "bb", button: [{ properties: { btnTest1: "aa", btnTest2: "bb" } }] } }];

console.log(remove(test));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Nenad Vracar
Nenad Vracar

Reputation: 122047

You could use reduce method with for..in loop to also iterate through object in cases there is no properties key. This solution assumes that when there is properties key there are no other keys in that object.

const test = [{"properties":{"test1":"aa","test2":"bb","button":[{"properties":{"btnTest1":"aa","btnTest2":"bb"}}]}},{"properties":{"test1":"aa","test2":"bb","button":[{"properties":{"btnTest1":"aa","btnTest2":"bb"}}]}}]

function f(data) {
  return data.reduce((r, e) => {
    if (e.properties) {
      r.push(...f([e.properties]))
    } else {
      const o = {}

      for (let p in e) {
        if (Array.isArray(e[p])) {
          o[p] = f(e[p])
        } else {
          o[p] = e[p]
        }
      }

      r.push(o)
    }

    return r
  }, [])
}

console.log(f(test))

Upvotes: 1

Related Questions