【问题标题】:How to write a function that takes a string and object and interpolates that object in the string?如何编写一个接受字符串和对象并将该对象插入字符串的函数?
【发布时间】:2016-10-06 13:29:50
【问题描述】:

大家好,我需要编写一个函数,该函数接受一个字符串和一个对象并将该对象插入到字符串中,就像这样

// interpolate("Its {weather} outside", {weather: 'damn Hot'})
// returns 'It's damn hot outside'


// interpolate( "Hi my name is {name}", {name: 'John'});
// returns 'Hi my name is John'

无论物体走多深都应该如此,这样的情况

// interpolate("Hi my name is {contact.name}", {contact: {name: 'john'}});

我有点卡住了,起初我尝试将字符串拆分为一个数组,然后尝试将对象值放入数组中,然后将其重新组合在一起,但这不适用于所有测试用例,有人可以帮我写这个吗功能并解释他们的解决方案吗?谢谢你

所以我尝试了类似的方法,但并不能真正适用于所有测试用例,这是一个模板文字,但该函数应该只将这些值作为参数单独工作,否则我很卡住。 .

function interpolate(strings, ...keys) {
  return (function(...values) {
    var dict = values[values.length - 1] || {};
    var result = [strings[0]];
    keys.forEach(function(key, i) {
      var value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join('');
  });
}

var t1Closure = interpolate`${0}${1}${0}!`;
t1Closure('Y', 'A');  // "YAY!" 
var t2Closure = interpolate`${0} ${'foo'}!`;
console.log(t2Closure('Hello', {foo: 'World'}));  // "Hello World!"

好的,我越来越近了,所以我将问题分成两个函数并需要将它们组合起来,唯一的问题是我不确定如何让最后一个用例在没有模板文字的情况下工作

var something = "something";
var sub = function(str) {
   return str.replace(/#\{(.*?)\}/g,
    function(whole, expr) {
      return eval(expr)
    })
}

console.log(sub("hello #{something}"));



var objectValue = function(str, obj){

     for(key in obj) {
       if(obj.hasOwnProperty(key)) {
          var value = obj[key];
          return str + value;
      }
   }
}


console.log(objectValue("hi my name is ", {contact: {name: 'john'}}));

【问题讨论】:

标签: javascript


【解决方案1】:

给你:

'use strict';
function interpolate(str, obj) {
  for (let prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        str = str.replace(new RegExp(`{${prop}}`, 'g'), obj[prop]);
    }
  }
  return str;
}
console.log(interpolate("Its {weather} outside", {weather: 'damn Hot'}));
// Its damn Hot outside

【讨论】:

    【解决方案2】:

    聚会有点晚了,但如果你不能(不想)使用任何外部库或 ES6,这里的想法是:

    function getMatches(s) {
        var regExp = /{([^}]*)}/g,
            matches = [],
            match;
    
        while ((match = regExp.exec(s)) != null) {
            matches.push(match[1]);
        }
        return matches;
    }
    
    function objValue(obj, i) {
        return obj[i];
    }
    
    function interpolate(s, obj) {
        var matches = getMatches(s),
            result = s;
    
        matches.forEach(function (match) {
            var props = match.split('.'),
                value = props.reduce(objValue, obj) || '';
    
            result = result.replace('{' + match + '}', value);
        });
        return result;
    }
    

    用法

    interpolate("Its {weather} outside", { weather: 'damn Hot' });
    

    JSFiddle.

    【讨论】:

      【解决方案3】:

      使用可怕的eval

      如果你控制你传递的字符串并认为它是安全的,你可以使用eval

      function interpolate (str, obj)  {
          return str.replace(/\{(.*?)\}/g, function (_, ref) {
              return eval('obj.' + ref);
          });
      }
      
      var output = interpolate("Its {weather} outside", {weather: 'damn Hot'});
      console.log(output);
      
      output = interpolate("Hi my name is {contact.name}", {contact: {name: 'john'}});
      console.log(output);
      
      output = interpolate("The highest bid is {rank[0].bid}", {rank: [{bid: 900}, {bid:600}]});
      console.log(output);

      请注意,如果给定一个类似'{x;alert("hi")}' 的字符串,上述函数将执行该alert 或任何其他代码。因此,如果字符串由用户提供(或可以更改),这不是一个好的解决方案。

      模板文字

      它没有遵循您的函数描述符,但template literals 已经提供了您正在寻找的功能:

      var weather = 'damn Hot';
      var output = `It's ${weather} outside`;
      console.log(output);
      
      var contact = {name: 'john'};
      var output = `Hi my name is ${contact.name}`;
      console.log(output);

      【讨论】:

      • 在 IE 中不起作用,但那又如何呢? :p。非常好的解决方案。
      【解决方案4】:

      或 lodash 模板。 Lodash 已经有很多方便的功能,我认为你最终会使用很多。

      var str = _.template('Its <%= weather %> outside')({weather: 'damn Hot'});
      
      // If you wanted to use the {{:var}} syntax.
      _.templateSettings.interpolate = /{{:([\s\S]+?)}}/g;
      var str = _.template('Its {{:weather}} outside')({weather: 'damn Hot'});
      

      【讨论】:

        【解决方案5】:

        试试renderjs

        $("<p>Its {{:weather}} outside</p>").render({weather: 'damn Hot'}) 
        -> <p>Its damn Hot outside</p>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-15
          • 2021-10-22
          • 2023-02-02
          • 2019-04-30
          • 2015-09-22
          • 2019-05-22
          • 1970-01-01
          相关资源
          最近更新 更多