Home > OS >  How to find in string in the syntax and split them into an array regardless of order?
How to find in string in the syntax and split them into an array regardless of order?

Time:07-20

I am trying to split an string into separate parts. Here how I want

I got an original string

let allString =  'This is the test to replace the string';

I will make the original string into array according to an array.

let toReplace = [
    {
        string: 'the test'
    },
    {
        string: 'replace'
    },
]

The result I want [ 'This is ', 'the test', ' to ', 'replace', ' the string' ].

I got the answer for this already

const processedText = toReplace
    .reduce(
      (result, { string }, index) => {
        const parts = result[result.length - 1].split(string);
        const [before, after] = parts;

        const newResult = result.slice();
        const firstPass = index === 0;
        if (firstPass) {
          newResult.shift();
        } else {
          newResult.pop();
        }

        if (before) {
          newResult.push(before);
        }
        if (string) {
          newResult.push(string);
        }
        if (after) {
          newResult.push(after);
        }

        return newResult;
      },
      [allString]
   )

The thing is if I change the order of the toReplace array, It won't work anymore

let toReplace = [
        {
            string: 'replace'
        },
        {
            string: 'the test'
        },
    ]

It will skip the 2nd one. Result [ 'This is the test to ', 'replace', ' the string', 'the test' ]

How can I fix this behavior?

CodePudding user response:

You can pass a regular expression to split. Using capturing groups will keep the separator in the array:

let allString = 'This is the test to replace the string';

const processedText = allString.split(/(the test|replace)/);
console.log(processedText);

The order isn't important for this:

let allString = 'This is the test to replace the string';

const processedText = allString.split(/(replace|the test)/);
console.log(processedText);

You can dynamically build the regular expression:

let toReplace = [{ string: 'the test' }, { string: 'replace' }];

const re = new RegExp(`(${toReplace.map(el => el.string).join('|')})`);

let allString = 'This is the test to replace the string';

const processedText = allString.split(re);
console.log(processedText);

CodePudding user response:

You could collect the indices of the wanted prases and sort the array by index and get the sliced array with it.

const
    text =  'This is the test to replace the string',
    toReplace = [{ string: 'replace' }, { string: 'the test' }],
    indices = [],
    result = [];

for (const { string } of toReplace) {
    let i = text.indexOf(string);
    while (i !== -1) {
        indices.push([i, string]);
        i = text.indexOf(string, i   string.length);
    }
}

indices.sort(([a], [b]) => a - b);

let i = 0, j = 0;

if (indices[j]?.[0] === 0) {
    result.push(indices[j][1]);
    i  = indices[j][1].length;
    j  ;
}

while (i < text.length && j < indices.length) {
    result.push(text.slice(i, indices[j][0]), indices[j][1]);
    i = indices[j][0]   indices[j][1].length;
    j  ;
}

if (text.slice(i)) result.push(text.slice(i));

console.log(result);
console.log(indices);

  • Related