简体   繁体   中英

Best way to join two adjacent array elements at each nth index

Assuming the following array example:

const arr = ['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana']

how do I convert it to look like this:

const result = ['mango apple', 'kiwi', 'melon orange', 'banana']

I've tried with a foor loop, but I'm unsure of the algorithm in the if condition or if it's even the best way, or perhaps reduce is better?

 const arr = ['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana'] let n = [] for (let i = 0; i < arr.length; i++ ) { //Something like simply: i % 2 == 0 //Is obviously not good enough if (/* What here?*/) { n.push(arr[i] + ' ' + arr[i+1]) } else { n.push(arr[i]) } }

You can use modulus ( % ) for this, here is an example:

 var arr = ['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana']; var result = []; for (let i = 0; i < arr.length; i++) { if (i % 3 == 0 && i + 1 < arr.length) { result.push(`${arr[i]} ${arr[i + 1]}`); i++; } else { result.push(arr[i]); } } console.log(result);

One way of doing this is like this:

 const arr = ['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana', 1, 2 ,3, 4, 5, 6] let n = [] for (let i = 0; i < arr.length; i+=3 ) { n.push(arr[i] + ' ' + arr[i+1]); n.push(arr[i+2]); } console.log(n); // output // ["mango apple", "kiwi", "melon orange", "banana", "1 2", 3, "4 5", 6]

EDIT: As per Shiva's comment, I have modified code to handle out of index values

const arr = ['mango', 'apple', 'kiwi', 'melon']
let n = []
for (let i = 0; i < arr.length; i+=3 ) {
    if(arr[i] === undefined) {
        break;
    }

    let first = arr[i];
    if(arr[i+1] !== undefined) {
        first+= ' ' + arr[i+1];
    }
    n.push(first);
    if(arr[i+2] !== undefined) {
        n.push(arr[i+2]);
    }
}
console.log(n);
// output
// ["mango apple", "kiwi", "melon"]

You could take an offset for getting the real index i + offset and iterate a virtual index i for getting the check done.

 var array = ['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana'], n = 2, offset = 0, result = []; for (let i = 0; i + offset < array.length; i++) { result.push(i % n == 0 ? array[i + offset] + ' ' + array[i + 1 + offset++] : array[i + offset] ); } console.log(result);

An approach with a generator function.

 function* getNTh(array, n) { var i = 0, offset = 0; while (i + offset < array.length) { yield i % n == 0 ? array[i + offset] + ' ' + array[i + 1 + offset++] : array[i + offset]; i++; } } console.log([...getNTh(['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana'], 2)]); console.log([...getNTh(['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana'], 3)]);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

I'm a big fan of re-using code. IOW: I'm a lazy programmer. :)

As such from what I can gather the OP is really after a pattern iterator. Because something like this might be useful for the future this is something I'd try and generalise and make into a function.

With this in mind, I'm a big fan of the new Javascript feature called Iterators and generators. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators and this problems seems to fit nicely here for something that could get re-used again & again.

ps. Even if you want to target browsers that don't have generators yet, save yourself a life of misery and get your Javscript transpiled. Most modern browsers already have good support too -> https://caniuse.com/#feat=es6-generators

Below is an example, and you can see how easy it is then to change the pattern, without having to worry about modulus & stepping etc.

 function *patternIter(pattern, len) { let p = 0, ps = pattern[p], c; for (l = 0; l < len; l += 1) { if (!c) c = {offset: l, size: 0}; c.size += 1; if (c.size === ps) { yield c; c = undefined; p += 1; ps = pattern[p % pattern.length]; } } if (c) yield c; } const arr = ['mango', 'apple', 'kiwi', 'melon', 'orange', 'banana'] function showPattern(p) { console.log('Pattern ' + p.join(", ")); console.log( [...patternIter(p, arr.length)] .map(m => arr.slice(m.offset, m.offset + m.size) .join(" ")).join(", ") ); } showPattern([1, 2]); showPattern([3, 2, 1]); showPattern([1, 3, 2]); showPattern([3, 1]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM