goddamnyouryan
goddamnyouryan

Reputation: 6896

Break string into array with combination of every x words

I have a long javascript string. I am trying to break it into an array with every x combination of consecutive words. So for example if my array

var string = 'This is my example string'

and my x was equal to 3 I would get something like:

['This', 'This is', 'This is my', 'is', 'is my', 'is my example', 'my', 'my example', 'my example string', 'example string', 'string']

So like, every combination of up to three words. I am using this as an index to do fuzzy text matching on.

Upvotes: 0

Views: 198

Answers (3)

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64933

A purely functional approach:

// permuteWords :: Number -> String -> [String]
const permuteWords = count => x => {
    const words = x.split (' ')
    const wordIndexes = [...words.keys ()]

    return wordIndexes.flatMap (i => {
        const wordIndexes_ = wordIndexes.slice (i, count + i)

        return wordIndexes_.map (i_ => 
            words.slice (i, i_ + 1).join (' ')
        )
    })
}

const output = permuteWords (3) ('This is my example string')

console.log (output)

2nd take: More segmentation to make things simpler!

Now I've defined permuteBy to produce a flat array of indices representing the permutations, and I use them to sequentially get each word:

// rangeFromZero :: Number -> [Number]
const rangeFromZero = x => [...Array (x).keys ()]

// permuteBy :: Number -> Number -> [Number]
const permuteBy = x => y => {
    const ys = rangeFromZero (y)

    return ys.flatMap(i => 
        ys.slice (i, x + i).flatMap (i_ => ys.slice(i, i_ + 1))
    )
}

// permuteWords :: Number -> String -> [String]
const permuteWords = count => x => {
    const words = x.split (' ')
    
    return permuteBy (count) (words.length)
                  .map (i => words[i])
}

const output = permuteWords (3) ('This is my example string')

console.log (output)

Upvotes: 1

trincot
trincot

Reputation: 350147

You could use a double for loop:

function chunks(str, len) {
    const arr = str.match(/\S+/g);
    const result = [];
    for (let i = 0; i < arr.length; i++) {
        const end = Math.min(arr.length, i + len);
        for (let j = i + 1; j <= end; j++) {
            result.push(arr.slice(i, j).join(" "));
        }
    }
    return result;
}


var string = 'This is my example string';
console.log(chunks(string, 3));

And a more functional approach would be:

function chunks(str, len) {
    return str.match(/\S+/g).flatMap((_, i, arr) => 
        arr.slice(i, i + len).map((_, j) => arr.slice(i, i+j+1).join(" "))
    );
}

var string = 'This is my example string';
console.log(chunks(string, 3));

Upvotes: 3

Nina Scholz
Nina Scholz

Reputation: 386560

You could reduce the array and take a Set for getting unque values.

var string = 'This is my example string',
    result = [... new Set(string.split(' ').reduce((r, s, i, a) =>
        r.concat(
            s,
            a.slice(i, i + 2).join(' '),
            a.slice(i, i + 3).join(' ')
        ),
        []
    ))];

console.log(result);

Upvotes: 2

Related Questions