skip to Main Content

i wish to make a utility function – which takes in an input – vanilla plain object – such that – it recursively traverses it to the deepest level even if a value is an array, it should iterate over its individual elements and for each array value’s element or field’s value- it checks –

  1. if the currently iterated value is nullish (null or undefined) – it make the value "NULL_VALUE" as a string,
  2. if the currently iterated value is empty string (""), then it makes the value "EMPTY_VALUE" as a string,
  3. if the currently iterated value is empty array ( [] ), then it makes the value "EMPTY_ARRAY" as a string,
  4. if the currently iterated value is object array ( { } ), then it makes the value "EMPTY_OBJECT" as a string,
  5. and finally if its any value other than above then the value is made "VALID_VALUE" as a string

Example

const input = {
  a: null,
  b: "",
  c: [],
  d: {},
  e: "hello",
  f: [null, "", [], {}, "world"],
  g: {
    h: null,
    i: "",
    j: [],
    k: {},
    l: "nested",
  },
};

Output

{
  a: "NULL_VALUE",
  b: "EMPTY_VALUE",
  c: "EMPTY_ARRAY",
  d: "EMPTY_OBJECT",
  e: "VALID_VALUE",
  f: ["NULL_VALUE", "EMPTY_VALUE", "EMPTY_ARRAY", "EMPTY_OBJECT", "VALID_VALUE"],
  g: {
    h: "NULL_VALUE",
    i: "EMPTY_VALUE",
    j: "EMPTY_ARRAY",
    k: "EMPTY_OBJECT",
    l: "VALID_VALUE",
  },
}

My current approach is as follows where for very nested object it doesnt exactly work as intended as some empty arrays and objects are skipped

const transformObject = (obj) => {
const transformedObj = {};
for (const key in obj) {
    const value = obj[key];
    if (Array.isArray(value)) {
        transformedObj[key] = transformValue(transformArray(value));
    } else if (isPlainObject(value)) {
        transformedObj[key] = transformValue(transformObject(value));
    } else {
        transformedObj[key] = transformValue(value);
    }
}
return transformedObj;

};

const transformArray = (arr: any[]): any[] => {
return arr.map((item) => {
    if (isPlainObject(item)) return transformObject(item);
    if (Array.isArray(item)) return transformArray(item);
    return transformValue(item);
});

};

const transformValue = (value: any): any => {
if (value === null || value === undefined) return "NULL_VALUE";
if (value === "") return "EMPTY_VALUE";
if (Array.isArray(value) && value.length === 0) return "EMPTY_ARRAY";
if (isPlainObject(value) && Object.keys(value).length === 0)
    return "EMPTY_OBJECT";
return value;

};

2

Answers


  1. Here’s a similar recursive approach

    const input = {a:null,b:"",c:[],d:{},e:"hello",f:[null,"",[],{},"world"],g:{h:null,i:"",j:[],k:{},l:"nested"}};
    
    const transformObject = (obj) => {
      if (obj === undefined || obj === null) return "NULL_VALUE";
    
      if (obj === "") return "EMPTY_VALUE";
    
      if (Array.isArray(obj))
        return obj.length ? obj.map(transformObject) : "EMPTY_ARRAY";
    
      if (typeof obj === "object") {
        const entries = Object.entries(obj);
    
        return entries.length ?
          entries.reduce((acc, [key, value]) => {
            acc[key] = transformObject(value);
            return acc;
          }, {}) :
          "EMPTY_OBJECT";
      }
    
      return "VALID_VALUE";
    };
    
    console.log(transformObject(input))
    Login or Signup to reply.
  2. Here some function, F, that maps the input t to the desired output –

    const F = (t) => {
      switch (t?.constructor) {
        case Object:
          const keys = Object.keys(t)
          if (keys.length == 0) return "EMPTY_OBJECT"
          return Object.fromEntries(keys.map(k => [k, F(t[k])]))
        case Array:
          if (t.length == 0) return "EMPTY_ARRAY"
          return t.map((v, k) => F(v))
        case String:
          if (t == "") return "EMPTY_VALUE"
          break
        case undefined:
          return "NULL_VALUE"
      }
      return "VALID_VALUE"
    }
    
    console.log(F({a:null,b:"",c:[],d:{},e:"hello",f:[null,"",[],{},"world"],g:{h:null,i:"",j:[],k:{},l:"nested"},}))

    And here’s a TypeScript version with added input I and output O types –

    type I = null | string | Array<I> | { [key: string]: I }
    
    type O =
      | "NULL_VALUE"
      | "EMPTY_VALUE"
      | "EMPTY_ARRAY"
      | "EMPTY_OBJECT"
      | "VALID_VALUE"
      | Array<O>
      | { [key: string]: O }
    
    const F = (t: I): O => {
      switch (t?.constructor) {
        case Object: {
          const keys = Object.keys(t)
          if (keys.length == 0) return "EMPTY_OBJECT"
          return Object.fromEntries(keys.map(k => [k, F(t[k])]))
        }
        case Array: {
          if (t.length == 0) return "EMPTY_ARRAY"
          return (t as Array<I>).map((v, k) => F(v))
        }
        case String: {
          if (t == "") return "EMPTY_VALUE"
          break
        }
        case undefined: {
          return "NULL_VALUE"
        }
      }
      return "VALID_VALUE"
    }```
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search