在每次出现特定子字符串时剪切数组中存在的 JS 字符串并附加到同一个数组
Posted
技术标签:
【中文标题】在每次出现特定子字符串时剪切数组中存在的 JS 字符串并附加到同一个数组【英文标题】:Cut JS string present in an array at every occurrance of a particular substring and append to same array 【发布时间】:2017-11-06 09:05:34 【问题描述】:注意: 在这个时间点,我无法更好地措辞问题标题。如果有人能够更好地表达它,请继续!
我有什么:
var array = ["authentication.$.order", "difference.$.user.$.otherinformation", ... , ...]
我需要什么:
["authentication", "authentication.$", "authentication.$.order",
"difference", "difference.$", "difference.$.user", "difference.$.user.$",
"difference.$.user.$.otherinformation"]
基本上,无论我在哪里看到.$.
,我都需要保留它,然后在.$.
出现之前附加所有内容以及.$
出现之前的所有内容
示例:
difference.$.user.$.otherinformation
应该被解析为包含:
difference
difference.$
difference.$.user
difference.$.user.$
difference.$.user.$.otherinformation
我强烈感觉这里会涉及到某种递归,但还没有朝那个方向发展。
下面是我的实现,但不幸的是,当我的子字符串与.$.
的第一次出现匹配时,它会停止并且不会继续进一步检查同一字符串中.$.
的其他出现。
我怎样才能最好地结束这个?
当前有缺陷的实现:
for(var i=0; i<array.length; i++)
// next, replace all array field references with $ as that is what autoform's pick() requires
// /\.\d+\./g,".$." ==> replace globally .[number]. with .$.
array[i] = array[i].replace(/\.\d+\./g,".$.");
if(array[i].substring(0, array[i].lastIndexOf('.$.')))
console.log("Substring without .$. " + array[i].substring(0, array[i].indexOf('.$.')));
console.log("Substring with .$ " + array[i].substring(0, array[i].indexOf('.$.')).concat(".$"));
array.push(array[i].substring(0, array[i].indexOf('.$.')).concat(".$"));
array.push(array[i].substring(0, array[i].indexOf('.$.')));
// finally remove any duplicates if any
array = _.uniq(array);
【问题讨论】:
【参考方案1】:使用一个简单的for
循环,如下所示:
var str = "difference.$.user.$.otherinformation";
var sub, initial = "";
var start = 0;
var pos = str.indexOf('.');
for (; pos != -1; pos = str.indexOf('.', pos + 1))
sub = str.substring(start, pos);
console.log(initial + sub);
initial += sub;
start = pos;
console.log(str);
【讨论】:
【参考方案2】:一个功能单一的衬里可以是;
var array = ["authentication.$.order", "difference.$.user.$.otherinformation"],
result = array.reduce((r,s) => r.concat(s.split(".").reduce((p,c,i) => p.concat(i ? p[p.length-1] + "." + c : c), [])), []);
console.log(result);
【讨论】:
迄今为止在紧凑性方面最短的答案,但在可理解性方面却很复杂。您能解释一下这实际上是如何工作的吗? 如果数组包含如下值怎么办:"www.example.com."
?
@hindmost - 好问题,但我的初始数组永远不会包含以 .
结尾的东西,所以我想可以安全地假设。【参考方案3】:
这个问题实际上不需要递归。您可以将常规循环与子循环一起使用。
你只需要:
-
将数组中的每个出现拆分为子字符串;
从这些子字符串中构建一系列累积值;
用这个系列替换数组的当前元素。
此外,为了使替换正常工作,您必须以相反的顺序迭代数组。顺便说一句,在这种情况下,您不需要删除数组中的重复项。
所以代码应该是这样的:
var array = ["authentication.$.order", "difference.$.user.$.otherinformation"];
var SEP = '.$.';
for (var i = array.length-1; i >= 0; i--)
var v = array[i];
var subs = v.replace(/\.\d+\./g, SEP).split(SEP)
if (subs.length <= 1) continue;
var acc = subs[0], elems = [acc];
for (var n = subs.length-1, j = 0; j < n; j++)
elems[j * 2 + 1] = (acc += SEP);
elems[j * 2 + 2] = (acc += subs[j]);
array.splice.apply(array, [i, 1].concat(elems));
console.log(array);
【讨论】:
我在 chrome 控制台中试了一下这段代码 sn-p 以了解发生了什么。但是,输出似乎与所需的有所不同。输出:,difference.$.,difference.$.difference,difference.$.difference.$.,difference.$.difference.$.user
@blueren 抱歉,我忘了用subs[0]
初始化elems
。现在可以了【参考方案4】:
你可以使用reduce如下:
const dat = ["authentication.$.order", "difference.$.user.$.otherinformation"];
const ret = dat.reduce((acc, val) =>
const props = val.split('.');
let concat = '';
return acc.concat(props.reduce((acc1, prop) =>
concat+= (concat ? '.'+ prop : prop);
acc1.push(concat);
return acc1;
, []));
, [])
console.log(ret);
【讨论】:
【参考方案5】:我使用正则表达式来抓取所有内容,直到最后一次出现 .$
并将其切碎,直到什么都没有。最后反转。
let results = [];
let found = true;
const regex = /^(.*)\.\$/g;
let str = `difference.\$.user.\$.otherinformation`;
let m;
results.push(str);
while(found)
found = false;
while ((m = regex.exec(str)) !== null)
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex)
regex.lastIndex++;
if(m.length > 0)
found = true;
results.push(m[0]);
str = m[1];
results.push(str);
results = results.reverse();
// Concat this onto another array and keep concatenating for the other strings
console.log(results);
你只需要在你的数组上循环,将结果存储在一个临时数组中,然后继续将它们连接到一个最终数组中。
https://jsfiddle.net/9pa3hr46/
【讨论】:
这有点不对...结果是:difference,difference.$,difference.$.user.$,difference.$.user.$.otherinformation
注意difference.$.user
已被跳过。【参考方案6】:
你可以在你的数组循环中使用这个函数。
var test = "difference.$.user.$.otherinformation";
function toArray(testString)
var testArr = testString.split(".")
var tempString = "";
var finalArray = [];
for (var i = 0; i < testArr.length; i++)
var toTest = testArr[i];
if (toTest == "$")
tempString += ".$"
else
if (i != 0)
tempString += ".";
tempString += toTest;
finalArray.push(tempString)
return finalArray;
console.log(toArray(test))
【讨论】:
以上是关于在每次出现特定子字符串时剪切数组中存在的 JS 字符串并附加到同一个数组的主要内容,如果未能解决你的问题,请参考以下文章