2015-08-30 2 views
1

Я пытаюсь написать функцию, которая берет строку и заглавывает первую букву в каждом слове, не включенном в строку «minorWords». Что отсутствует в моем коде, что приводит к тому, что возвращаемое значение будет «неопределенным»? После написания этой функции несколько разных способов, я теперь думаю, что я просто использую .forEach неправильно. Я вполне уверен, что я использую тернарный оператор соответствующим образом, но я попытался заменить оператор if и получил тот же результат (неопределенный). Я также не уверен, почему undefined возвращается дважды. , ,Javascript тернарный оператор внутри forEach возвращает undefined

function titleCase1(title, minorWords) { 
    var titleArray = title.split(" "); 
    var minorArray = minorWords.split(" "); 
    var newArray = titleArray.forEach(function(word){ 
    (word in minorArray)? word : 
     word[0].toUpperCase() + word.slice(1); 
    }) 
    console.log(newArray); 
} 

titleCase1("the wind in the willows", "the in"); 
// -> undefined undefined 

Я понимаю, что, если это работает первый «» не будут капитализированы, но я не полагаю, что один раз я уже не злоупотребляя инструменты я здесь. , ,

+1

Это потому, что ты ничего не делать с '' слово' или слово [0]. toUpperCase() + word.slice (1) '. Вероятно, вы выбрали 'map' вместо' forEach' и забыли «вернуть» значение. – Xufox

+1

Взгляните на: http: // stackoverflow.com/questions/4878756/javascript-how-to-capitalize-first-letter-of-each-word-like-a-2-word-city – jwkicklighter

+1

И 'undefined' не возвращается дважды, он возвращается один раз и _logged_ once , У вас нет оператора 'return' в' titleCase1'. – Xufox

ответ

1

Там вы две проблемы с кодом:

  1. Единственное, что forEach делает выполнение обратного вызова для каждого элемента в массиве и ничего не возвращает, поэтому newArray всегда будет undefined. Для справки проверьте, как работает forEachhere.

    Если вы хотите создать новый массив со значениями, например, как вы пытаетесь сделать с newArray. Вам нужно использовать map, но вам действительно нужно вернуть значение из обратного вызова. Для справки проверьте, как работает maphere.

  2. Вы не можете использовать оператора in, чтобы узнать, есть ли в вашем массиве слово. Оператор in проверяет, присутствует ли указанное свойство в указанном объекте. Поэтому он всегда будет возвращать false при использовании для проверки элемента внутри массива. Поскольку массив в javascript на самом деле является объектом под капотом!

    вар а = [ 'а', 'B', 'C' ];

    фактически

    вар а = {0 : 'а', 1: 'B', 2: 'с' };

    Поэтому 'a' in [ 'a', 'b', 'c' ] всегда будет возвращать false и, например, 0 in [ 'a', 'b', 'c' ] вернет true.

    Из-за этой оговорки вы должны изменить свой подход и, например, использовать indexOf. Для справки проверьте, как indexOf работает here.

Имея это в виду, вы можете изменить свой код к следующему, чтобы получить желаемое поведение:

function titleCase1(title, minorWords) { 
    var titleArray = title.split(' '); 
    var minorArray = minorWords.split(' '); 
    var newArray = titleArray.map(function (word) { 

    // indexOf returns the elements index on match or -1. 
    var match = minorArray.indexOf(word) != -1; 

    // If there's a match, return the (lowercased) word, otherwise uppercase it.  
    return match ? word : (word[0].toUpperCase() + word.slice(1)); 
    }); 

    console.log(newArray); 
} 

titleCase1("the wind in the willows", "the in"); // [ 'the', 'Wind', 'in', 'the', 'Willows' ]