0

I need to do a deep-iteration of a javascript object that can have nested objects and arrays and I need to execute a function on all of the numeric values and modify the object.

For example, lets say I need to multiply every number by 2.

const foo = (obj) => {
    // multiply every numeric value by 2 
};

const modified = foo({
    a: 0,
    b: 3,
    c: {
      d: 4,
      e: {
          f: 6,
          g: [ 0, 3, 7, 3 ]
      }
    }
});

The value of modified should be:

{
    a: 0,
    b: 6,
    c: {
      d: 8,
      e: {
          f: 12,
          g: [ 0, 6, 14, 6 ]
      }
    }
}

Since people typically want to know what you've tried, here's how far I got before being completely stumped.

const obj = {};
for(key in object) {
    const item = object[key];
    if(typeof item === 'object') {
        // The levels deep is dynamic, so how would I keep doing this..
    } else if(typeof item === 'array') {
        obj[key] = item.map((a, b) => a * 2);
    } else if(!isNaN(item)) {
        obj[key] = item * 2;
    }
}
Hobbyist
  • 15,888
  • 9
  • 46
  • 98
  • See [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/q/11922383/218196) - *What if the "depth" of the data structure is unknown to me?* . – Felix Kling Apr 16 '17 at 01:03

3 Answers3

2

You probably want recursion in this case. This implementation works for any type of object and mapping function you give it, aka extremely generic

function mapper(obj, mappingFn, result) {
  if (!result)
      result = {};
  Object.keys(obj)
        .forEach(key => {
            switch (typeof obj[key]) {
                case 'string':
                case 'number':
                    result[key] = mappingFn(obj[key]);
                    break;
                // if obj[key] is an array, it still returns 'object', so we are good
                case 'object':
                    mapper(obj[key], mappingFn, result);
                    break;
            }
        });
  return result;
}

let data = {
    a: 0,
    b: 3,
    c: {
      d: 4,
      e: {
          f: 6,
          g: [ 0, 3, 7, 3 ]
      }
    }
};

let result = mapper(data, value => value * 2);
console.log(result) // everything should be multiplied by 2
Trash Can
  • 6,608
  • 5
  • 24
  • 38
2

Using recursion and expanding on your solution

function multiplyByTwo(objectToParse) {
  const obj = {};
  for (key in objectToParse) {
    const item = object[key];
    if (typeof item === 'object') {
        obj[key] = multiplyByTwo(item);
    } else if (typeof item === 'array') {
      obj[key] = item.map((a, b) => a * 2);
    } else if (!isNaN(item)) {
      obj[key] = item * 2;
    }
  }
  return obj;
}

const result = multiplyByTwo(object);
Divyun
  • 96
  • 4
-2

There's my solution.

const foo = (obj, operation) => {
  let afterObj = obj;

  for(item in afterObj) {
    if(typeof afterObj[item] == "object") {
        foo(afterObj[item], operation);
    } else if (typeof afterObj[item] = "string") {
    } else {
        afterObj[item] = operation(afterObj[item]);
    }
  }

  return afterObj;
};

const modified = foo({
    a: 0,
    b: 3,
    c: {
      d: 4,
      e: {
          f: 6,
          g: [ 0, 3, 7, 3 ]
      }
    }
}, function(x) { return x*2 });
Jakub Chlebowicz
  • 509
  • 1
  • 6
  • 12