John Winston
John Winston

Reputation: 1471

How to use recursion to turn object into string?

EDIT

To me JSON.stringify is not the solution here, as it is much slower than recursion

    JSON.stringify(fakeData)
        .replace(/,/g, ';')
        .replace(/:(?={)/g, '')
        .replace(/"/g, '')
//Result
Recursion with reduce x 816,321 ops/sec ±7.38% (80 runs sampled)
JSON.stringify x 578,221 ops/sec ±1.72% (92 runs sampled)
Fastest is Recursion with reduce

I am making a css-in-js library, and I need to use recursion to turn object into string like this:

Input:

const fakeData = {
  a: {
    b: 'c',
    d: 'e'
  }
}

Output:

a{b:c;d:e;}

My recursion function:

const buildKeyframe = (obj) => {
    return Object.entries(obj).reduce((acc, [prop, value]) => {
        if (typeof value === 'string') {
            return `${acc}${prop}:${value};`
        }

        return `${prop}:{${buildKeyframe(value)}}`
    }, '')
}

This function works, but I think there is room for improvement(e.g. use TCO, avoid using reduce)... How can I write a better function to recurse this data structure?

Upvotes: 1

Views: 120

Answers (1)

MM2021
MM2021

Reputation: 150

This solution is about 50% faster and also works with more than one css property

const buildKeyframe = obj => {
          let result = '';

          for (const key in obj) {
              let value = obj[key];
              if(obj.hasOwnProperty(key)) {
                result += typeof value === 'string' ?
                 `${key}:${value};` :
                 `${key}{${buildKeyframe(value)}}`;
              }
          }

          return result;
    }

const fakeData = {
a: {
    b: 'c',
    d: 'e',
    g: 'b',
},
b: {
    m: 'n'
}
}

console.log(buildKeyframe(fakeData));

Benchmark.js Test results:

for...in x 1,875,280 ops/sec ±0.40% (87 runs sampled)
reduce x 1,272,530 ops/sec ±0.27% (91 runs sampled)
Fastest is for...in

Upvotes: 1

Related Questions