替换对象(和/或数组)中字符串的所有实例 - JavaScript [英] Replace all instances of a string within an object (and/or array) - JavaScript

查看:45
本文介绍了替换对象(和/或数组)中字符串的所有实例 - JavaScript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

搜索未知深度和属性的 JavaScript 对象并替换给定字符串的所有实例的最佳方法是什么?

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')));

小提琴:http://jsfiddle.net/93Uf4/3/

推荐答案

在您提出自己的方式旁边,这是一个经典的循环方法.正如有人在评论中提到的那样,它更稳定,因为在尝试解析它时,您不会冒着搞砸对象并抛出错误的风险.另一方面,出现了一些问题(见底部).

Next to the way you proposed yourself, here is a classic loop approach. As mentioned by someone in a comment, 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).

但是要小心,因为 needle 将用作正则表达式.您可能需要考虑在其中添加某种引用.

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.

我希望我没有忽略任何东西,所以测试它并尝试一下.在这里你可以找到一个fiddle.

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 become "undebazed"?
console.log( Object.replaceAll( { x: undefined }, "fin", "baz" ) );

// null or "nalala"?
console.log( Object.replaceAll( { x: null }, "ull", "alala" ) );

// true or false?
console.log( Object.replaceAll( { x: true }, "true", "false" ) );

// true or "foo"?
console.log( Object.replaceAll( { x: true }, "true", "foo" ) );

数字也一样

// 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.

这篇关于替换对象(和/或数组)中字符串的所有实例 - JavaScript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆