given input str1 is "abc" and str2 is "def" output should be adbecf and given str1 = "ab" and str2 = "def" output should be adbef
my output has been:
merge('abc','def') "adbecfNaN"
merge('ab','def') "adbeundefinedf"
I have been attempting to filter undefined and NAN, but it's not working.
Here's my code:
function merge (str1, str2) {
var a = str1.split("").filter(Boolean);
var b = str2.split("");
var mergedString = '';
for(var i = 0; i <= a.length && i <= b.length; i++) {
mergedString += a[i] + b[i];
}
return mergedString;
}
given input str1 is "abc" and str2 is "def" output should be adbecf and given str1 = "ab" and str2 = "def" output should be adbef
my output has been:
merge('abc','def') "adbecfNaN"
merge('ab','def') "adbeundefinedf"
I have been attempting to filter undefined and NAN, but it's not working.
Here's my code:
function merge (str1, str2) {
var a = str1.split("").filter(Boolean);
var b = str2.split("");
var mergedString = '';
for(var i = 0; i <= a.length && i <= b.length; i++) {
mergedString += a[i] + b[i];
}
return mergedString;
}
Share
Improve this question
edited Sep 6, 2017 at 5:07
Dij
9,8084 gold badges20 silver badges35 bronze badges
asked Sep 6, 2017 at 5:06
raj jarraj jar
651 gold badge1 silver badge5 bronze badges
2
|
14 Answers
Reset to default 4you need to use <
and not <=
in loop condition since array indexes are started from 0. That is why you are getting NaN. you can do something like this:
function merge (str1, str2) {
var a = str1.split("").filter(Boolean);
var b = str2.split("");
var mergedString = '';
for(var i = 0; i < a.length || i < b.length; i++) { //loop condition checks if i is less than a.length or b.length
if(i < a.length) //if i is less than a.length add a[i] to string first.
mergedString += a[i];
if(i < b.length) //if i is less than b.length add b[i] to string.
mergedString += b[i];
}
return mergedString;
}
console.log(merge('abc','def'));
console.log(merge('ab','def'));
The shortest way and probably the fastest, is to iterate the smallest length of the string and then take the rest of both string.
function zip(a, b) {
var i,
l = Math.min(a.length, b.length),
temp = '';
for( i = 0; i < l; i++) {
temp += a[i] + b[i];
}
return temp + a.slice(i) + b.slice(i);
}
console.log(zip('abc', '123')); // a1b2c3
console.log(zip('ab', '123')); // a1b23
console.log(zip('abcd', '12')); // a1b2cd
With ES6, you could use Array.from
with the built in mapper for the letters.
var a = "ab",
b = "def",
result = Array.from(a.length > b.length ? a : b, (_, i) => (a[i] || "") + (b[i] || ""))
.join('');
console.log(result);
You could use the effect of the String.raw
tag function here:
var a = "abc", b = "DEF";
var result = String.raw({ raw: a }, ...b) + b.substring(a.length - 1);
console.log(result);
This raw
property is expected to be an iterable that provides the raw strings that surround interpolated values which are provided by the other arguments (...b
). As a string is iterable (yielding its characters) the intended alteration is achieved.
If b
has fewer characters than a
, then the interpolated values are assumed empty (which is desired here). When b
has as many or more characters, then the remaining characters must be concatenated explicitly. We use substring
here instead of the also popular slice
, as it will treat a negative argument as 0, which is desired here.
A simple approach: Iterate over the longest string, output the combination of the characters at the current index, use the empty string if no character exists at the current index.
console.log(merge('ab','def'));
function merge(a, b){
for(var i = 0, s = '', l = Math.max(a.length, b.length); i < l; i++){
s += a.charAt(i) || '';
s += b.charAt(i) || '';
}
return s;
}
const merge = (str1, str2) => str1.length && `${str1[0]}${merge(str2, str1.slice(1))}` || str2;
console.log(merge('abc','def'));
console.log(merge('ab','def'));
How about simply use Array.reduce
?
function combineStrings(s1, s2) {
return [...s1].reduce((acc, v, i) => `${acc}${v}${s2[i]??``}`, ``);
}
console.log(
[
`combineStrings("abc", "DEF"), expect 'aDbEcF' => ${
combineStrings("abc", "DEF")}`,
`combineStrings("abcYZ", "DEF"), expect 'aDbEcFYZ' => ${
combineStrings("abcYZ", "DEF")}`,
`combineStrings("abc", "DEFYZ"), expect 'aDbEcF' => ${
combineStrings("abc", "DEFYZ")}`
].join(`\n`)
);
JS bin link -https://jsbin.com/nihoxivoxa/edit?js,console
function merge (str1, str2) {
var a = str1.split("");
var b = str2.split("");
var count = 0;
var merged_string = "";
//let's determine the loop counts, which depends on the smaller length of string
a.length < b.length ? count = a.length: count = b.length;
for( var i=0; i< count; i++){
merged_string += a[i]+b[i];
}
// add remaining characters
count < str1.length
? merged_string += str1.substr(count, str1.length)
: merged_string += str2.substr(count, str2.length)
return merged_string;
}
console.log(merge('ab','xysfergtrhyhn'))
function merge(s1, s2) {
var result = "";
for(var i=0; i<s1.length && i<s2.length; i++){
result+=s1[i]+s2[i];
}
s1.length<s2.length?result+=s2.substr(s1.length):result+=s1.substr(s2.length)
return result;
}
console.log(merge("abc","12345"));
console.log(merge("12345","abc"));
If you convert the strings to arrays, you can recursively shift the first element off of each array onto a new array, then continue until there are no elements left in both arrays, finally returning the new array.
const shift = (a, b) => a.length||b.length?[a.shift(), b.shift(), ...shift(a,b)]:[];
console.log(shift([...'acegik'],[...'bdfhjl']).join('')); // abcdefghijkl
console.log(shift([...'aceg' ],[...'bdfhjl']).join('')); // abcdefghjl
console.log(shift([...'acegik'],[...'bdfh' ]).join('')); // abcdefghik
With Lodash in ES6, it is possible to solve this problem in one line code:
_.zip('abc'.split(''), 'def'.split('')).reduce((prev, curr) => prev + curr.join(''), '');
Here, zip
function is provided by a node library called Lodash
, which can be installed from npm: https://lodash.com/
Here is a small function that will break down two strings to produce an array of characters in the same alternating sequence you described. You can then use join('')
to combine these characters into one string.
var m = (a, b) => a.length ? [a[0], ...m(b, a.slice(1))] : b;
var string1 = "SCE ESG!";
var string2 = "ERTMSAE";
var mix = m(string1, string2);
console.log(mix.join(''));
or if you need it to work for any number of input strings:
var m = (a = [], ...b) =>
b.length ? a.length ? [a[0], ...m(...b, a.slice(1))] : m(...b) : a;
var string1 = "SR SG";
var string2 = "EEMSE";
var string3 = "CTEA!";
var mix = m(string1, string2, string3);
console.log(mix.join(''));
let a = "abcdefghijklmnopqrstuvwxyz";
let b = "1234567890";
const mix1 = [...a].map((a, i) => b[i] ? `${a}${b[i]}` : a).join('');
const mix2 = [...a].reduce((p, c, i) => b[i] ? `${p}${c}${b[i]}` : `${p}${c}`, "");
console.log("MIX: ", '\n', mix1, '\n', mix2);
Hope you guys are here with me, I'm trying to answer this over ES6
You can achieve the answer using any one mixing listed above. I've used, .map and .reduce
const b = "123456 e";
const a = "123456 12345hello";
let res = "";
let len = a.length > b.length ? a.length: b.length;
for (let i = 0; i < len; i++) {
res +=( !a[i] || !b[i]) ? (a[i] ??= b[i]) : a[i] + b[i];
}
console.log(res);
we can use a while loop inside a function who return the result of the iteration of the two words index by index..
const mergeAlternately = function(word1, word2) {
let merged = "";
let i = 0;
let j = 0;
while (i < word1.length || j < word2.length) {
if (i < word1.length) {
merged += word1[i];
i++;
}
if (j < word2.length) {
merged += word2[j];
j++;
}
}
return merged;
};
a[i]
isundefined
wheni == a.length
; you wanti < a.length
instead of<=
. – Ry- ♦ Commented Sep 6, 2017 at 5:09