admin管理员组文章数量:1279118
What's the best way to search through a JavaScript object of unknown depth and properties and replace all instances of given string?
This works, but is it the best way?
var obj = {
'a' : 'The fooman poured the drinks.',
'b' : {
'c' : 'Dogs say fook, but what does the fox say?'
}
}
console.log (JSON.parse(JSON.stringify(obj).replace(/foo/g, 'bar')));
Fiddle: /
What's the best way to search through a JavaScript object of unknown depth and properties and replace all instances of given string?
This works, but is it the best way?
var obj = {
'a' : 'The fooman poured the drinks.',
'b' : {
'c' : 'Dogs say fook, but what does the fox say?'
}
}
console.log (JSON.parse(JSON.stringify(obj).replace(/foo/g, 'bar')));
Fiddle: http://jsfiddle/93Uf4/3/
Share Improve this question asked Apr 13, 2014 at 19:13 Andrew DownesAndrew Downes 5577 silver badges13 bronze badges 6- 1 I would do it the same way as you do. – bobthedeveloper Commented Apr 13, 2014 at 19:22
- 3 Do you want it to apply to both keys and values? Can the object contain functions? – Ingo Bürk Commented Apr 13, 2014 at 19:23
-
3
Using this method to replace
:
,'
,"
,{
or any such thing is likely to cause a plete meltdown. I'd write a function that does this using recursion. – mzedeler Commented Apr 13, 2014 at 19:31 -
Also, using the regex
/some string$/
won't behave the way most people would expect. – mzedeler Commented Apr 13, 2014 at 19:32 - In my particular case, just values but the keys will never contain the search term. The object does not contain functions. – Andrew Downes Commented Apr 13, 2014 at 21:11
1 Answer
Reset to default 9Next to the way you proposed yourself, here is a classic loop approach. As mentioned by someone in a ment, it's more stable because you don't risk screwing the object up and throwing an error when trying to parse it back. On the other hand, some questions arise (see bottom).
Be careful, though, as the needle
will be used as a regular expression. You may want to consider adding some sort of quoting to it.
I hope I didn't overlook anything, so test it and play around with it. Here you can find a fiddle.
/**
* Replaces all occurrences of needle (interpreted as a regular expression with replacement and returns the new object.
*
* @param entity The object on which the replacements should be applied to
* @param needle The search phrase (as a regular expression)
* @param replacement Replacement value
* @param affectsKeys[optional=true] Whether keys should be replaced
* @param affectsValues[optional=true] Whether values should be replaced
*/
Object.replaceAll = function (entity, needle, replacement, affectsKeys, affectsValues) {
affectsKeys = typeof affectsKeys === "undefined" ? true : affectsKeys;
affectsValues = typeof affectsValues === "undefined" ? true : affectsValues;
var newEntity = {},
regExp = new RegExp( needle, 'g' );
for( var property in entity ) {
if( !entity.hasOwnProperty( property ) ) {
continue;
}
var value = entity[property],
newProperty = property;
if( affectsKeys ) {
newProperty = property.replace( regExp, replacement );
}
if( affectsValues ) {
if( typeof value === "object" ) {
value = Object.replaceAll( value, needle, replacement, affectsKeys, affectsValues );
} else if( typeof value === "string" ) {
value = value.replace( regExp, replacement );
}
}
newEntity[newProperty] = value;
}
return newEntity;
};
The last two parameters are optional, so it's perfectly fine to just call it like this:
var replaced = Object.replaceAll( { fooman: "The dog is fooking" }, "foo", "bar" );
However, there are still edge cases where it's unclear what should happen. For example:
// do you expect it to stay undefined or change type and bee "undebazed"?
console.log( Object.replaceAll( { x: undefined }, "fin", "baz" ) );
// null or "nalala"?
console.log( Object.replaceAll( { x: null }, "ull", "alala" ) );
Or
// true or false?
console.log( Object.replaceAll( { x: true }, "true", "false" ) );
// true or "foo"?
console.log( Object.replaceAll( { x: true }, "true", "foo" ) );
And the same for numbers
// 1337 or 1007?
console.log( Object.replaceAll( { x: 1337 }, "33", "00" ) );
// 1337 or "1foo7"
console.log( Object.replaceAll( { x: 1337 }, "33", "foo" ) );
None of these cases are currently handled in my method – only objects (for nesting) and strings will be touched.
本文标签: Replace all instances of a string within an object (andor array)JavaScriptStack Overflow
版权声明:本文标题:Replace all instances of a string within an object (andor array) - JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741295665a2370802.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论