合并标记的模板文字片段:最佳算法?

问题描述

我有一个标记的模板文字片段生成器,看起来像这样:

function fragment(chunks,...args) {
  return new Fragment(chunks,args);
};

class Fragment {
  constructor(chunks,args) {
    this.chunks = chunks;
    this.args = args;
  }
}

想法是能够将标记的模板文字拆分为不同的部分,并具有merge函数,该函数将任意深度嵌套的片段树转换为chunks数组和args数组就好像它只是一个以标签开头的大模板文字:

function f() {}
function g() {}

const part = fragment`A ${f} B`

const nested = fragment`C ${part} D ${g} E ${part}`

const [chunks,args] = merge(nested)

console.log(chunks) // ["C A "," B D "," E A "," B"]
console.log(args) // [function f,function g,function f]

实现merge的最好,最有效的算法是什么?谢谢。

解决方法

由于模板文字有两个parallel arrays,所以有点难看,但这是我要做的:

function mergeInto(target,acc,{chunks: srcChunks,args: srcArgs}) {
    const {chunks: targetChunks,args: targetArgs} = target;
    for (var i=0; i<srcArgs.length; i++) {
        acc += srcChunks[i];
        if (srcArgs[i] instanceof Fragment) {
            acc = mergeInto(target,srcArgs[i]);
        } else {
            targetChunks.push(acc);
            targetArgs.push(srcArgs[i]);
            acc = "";
        }
    }
    return acc + srcChunks[i];
}

function merge(fragment) {
    const chunks = [],args = [];
    chunks.push(mergeInto({chunks,args},"",fragment));
    return [chunks,args];
}
,

这是另一种解释,尽管在没有看到更多数据样本的情况下对其执行没有完全信心。简而言之,如果在merge函数中处理chunksargs的管理,则不需要fragment函数...

function fragment(chunks,...args) {
  let chunksCopy = [];
  let argsCopy = [];
  for ( i = 0; i < args.length; i++ ) {
    if ( args[ i ] instanceof Fragment ) {
      chunksCopy[ i ] = chunks[ i ] + args[ i ].chunks[ 0 ];
      chunksCopy[ i + 1 ] = args[ i ].chunks[ 1 ] + chunks[ i + 1 ];
      //argsCopy.splice( i,args[ i ].args[ 0 ] );
      argsCopy[ i ] = args[ i ].args[ 0 ];
    } else {
      if ( chunksCopy[ i ] == null ) {
        chunksCopy[ i ] = chunks[ i ];
      }
      argsCopy[ i ] = args[ i ];
    }
  }
  if ( chunksCopy[ i ] == null ) {
    chunksCopy[ i ] = chunks[ i ];
  }
  return new Fragment( chunksCopy,argsCopy );
};

class Fragment {
  constructor( chunks,args ) {
    this.chunks = chunks;
    this.args = args;
  }
}

function f() {}
function g() {}

const part = fragment`A ${f} B`;
console.log( part );

const nested = fragment`C ${part} D ${g} E ${part}`;
console.log( nested )
console.log( nested.chunks );  // ["C A "," B D "," E A "," B"]
console.log( nested.args ) // [function f,function g,function f]

请注意,在使用“运行代码段”时,console.log( nested.args )似乎显示了第三个函数自变量作为对f()的第一个函数自变量的引用。为了更清楚地解释结果,请在浏览器调试模式下复制并运行以上内容...

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...