我正在寻找一种有效的方法来替换对象中的值,如果它们匹配某种模式。
var shapes = {
square: {
attr: {
stroke: '###',
'stroke-width': '%%%'
}
},
circle: {
attr: {
fill: '###',
'stroke-width': '%%%'
}
}
}
例如,我希望能够用特定形状的颜色替换所有'###'图案:
var square = replace(shapes.square, {
'###': '#333',
'%%%': 23
});
var circle = replace(shapes.circle, {
'###': '#111',
'%%%': 5
});
这将允许我快速设置各种对象的笔触和/或填充值。
有没有办法干净利落地做到这一点?也许使用Lodash或正则表达式?
答案 0 :(得分:4)
在lodash中,你有一个效用函数mapValues
function replaceStringsInObject(obj, findStr, replaceStr) {
return _.mapValues(obj, function(value){
if(_.isString(value)){
return value.replace(RegEx(findStr, 'gi'), replaceStr);
} else if(_.isObject(value)){
return replaceStringInObject(value, findStr, replaceStr);
} else {
return value;
}
});
}
答案 1 :(得分:2)
普通JS,不需要库:
var shapes = {
square: {
attr: {
stroke: '###',
'stroke-width': '%%%'
}
},
circle: {
attr: {
fill: '###',
'stroke-width': '%%%'
}
}
}
shapes = JSON.parse(
JSON.stringify(shapes).replace(/###/g,"red").replace(/%%%/g,"23")
)
console.log(shapes);
答案 2 :(得分:0)
JavaScript String.prototype.replace() API应该可以让您做到这一点!
您必须首先遍历对象的属性,但这应该是非常简单的。
答案 3 :(得分:0)
您可以使用_.transform来替换替换对象中传递的属性值。如果值不在替换中,则使用原始值。
function replace(src, repl) {
return {
attr: _.transform(src.attr, function(result, val, key) {
result[key] = repl[val] || val;
}, {})
};
}
var shapes = {
square: {
attr: {
stroke: '###',
'stroke-width': '%%%'
}
},
circle: {
attr: {
fill: '###',
'stroke-width': '%%%'
}
}
};
var square = replace(shapes.square, {
'###': '#333',
'%%%': 23
});
var circle = replace(shapes.circle, {
'###': '#111',
'%%%': 5
});
console.log(square);
console.log(circle);
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
答案 4 :(得分:0)
详细介绍meir answer(摆脱lodash依赖和循环处理):
function replaceStringsInObject(obj, findStr, replaceStr, cache = new Map()) {
if (cache && cache.has(obj)) return cache.get(obj);
const result = {};
cache && cache.set(obj, result);
for (let [key, value] of Object.entries(obj)) {
let v = null;
if(typeof value === 'string'){
v = value.replace(RegExp(findStr, 'gi'), replaceStr);
}
else if (Array.isArray(value)) {
v = value;
for (var i = 0; i < value.length; i++) {
v[i] = replaceStringsInObject(value, findStr, replaceStr, cache);
}
}
else if(typeof value === 'object'){
v = replaceStringsInObject(value, findStr, replaceStr, cache);
}
else {
v = value;
}
result[key] = v;
}
return result;
}
答案 5 :(得分:0)
这是 Quentin 给出的代码的一个版本。
function replaceStringsInObject(value, findStr, replaceStr) {
if (typeof value === "string") {
return findStr === value ? replaceStr : value;
} else if (value instanceof admin.firestore.Timestamp) {
return value;
} else if (value instanceof admin.firestore.GeoPoint) {
return value;
} else if (Array.isArray(value)) {
return value.map((arrayItem) =>
replaceStringsInObject(arrayItem, findStr, replaceStr)
);
} else if (typeof value === "object") {
const newObj = {};
for (let [key, oldInnerValue] of Object.entries(value)) {
const newInnerValue = replaceStringsInObject(
oldInnerValue,
findStr,
replaceStr
);
const newKey = key === findStr ? replaceStr : key;
newObj[newKey] = newInnerValue;
}
return newObj;
} else {
return value;
}
}