0

I'm a beginner in JS and just trying to understand what is going on in below code. Probably it's something stupid but - well, like I sayed, Im a beginner ;)

First it just split array which is an argument of makeFriendlyDates(['2016-07-01', '2016-08-04']); function.

So, at this stage everything is looking ok. However when I call function changeToFriendly(arr1); which only reason to exist is changing numbers into month name it somehow changes newArr as well.

So if I comment out this line: //changeToFriendly(newArr); then newArr is what is should be, but if the changeToFriendly(newArr); is called out it somehow changes newArr instead of just returning month name.

My question is how changeToFriendly(newArr); can change newArr if the function doesn't do anything with the array, just traversing it and checking number corresponding with month name.

function makeFriendlyDates(arr) {
  var newArr = [];
  var elem;
  for (elem in arr) {
    newArr.push(arr[elem].split('-'));
  }
  document.getElementById('result').innerHTML = newArr;

  function changeToFriendly(arr1) {
    var month = '';
    var elem1;
    for (elem1 in arr1) {
      if (arr1[elem1][1] = '01') {
        month = 'January';
      } else if (arr1[elem1][1] === '02') {
        month = 'February';
      } else if (arr1[elem1][1] === '03') {
        month = 'March';
      } else if (arr1[elem1][1] === '04') {
        month = 'April';
      } else if (arr1[elem1][1] === '05') {
        month = 'May';
      } else if (arr1[elem1][1] === '06') {
        month = 'June';
      } else if (arr1[elem1][1] === '07') {
        month = 'July';
      } else if (arr1[elem1][1] === '08') {
        month = 'August';
      } else if (arr1[elem1][1] === '09') {
        month = 'September';
      } else if (arr1[elem1][1] === '10') {
        month = 'October';
      } else if (arr1[elem1][1] === '11') {
        month = 'November';
      } else if (arr1[elem1][1] === '12') {
        month = 'December';
      }

    }
    document.getElementById('result1').innerHTML = newArr;
    return month;
  }

  changeToFriendly(newArr);
}
makeFriendlyDates(['2016-07-01', '2016-08-04']);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>

<body>

  <p id="result"></p>
  <p id="result1"></p>

</body>

</html>
4castle
  • 32,613
  • 11
  • 69
  • 106
S1awek
  • 1,524
  • 15
  • 13
  • 3
    `for..in` is for looping objects, not arrays; you want a regular `for` loop. – elclanrs Jan 05 '17 at 19:12
  • Isn't array an object as well? – S1awek Jan 05 '17 at 19:13
  • This is a very easy mistake to make. `for...in` is almost deceptive in its meaning. –  Jan 05 '17 at 19:14
  • 2
    There's a typo on `if (arr1[elem1][1] = '01') {` it should be `===` – 4castle Jan 05 '17 at 19:14
  • you could use the number of a month as index for an array with the month names. – Nina Scholz Jan 05 '17 at 19:15
  • TomSki, `for...in` loops across an objects *keys*. An array doesn't store its items by key. –  Jan 05 '17 at 19:15
  • 1
    Well, it is an object, but you want to loop it as an array, meaning you want to loop numeric indices, not unordered key-value pairs. – elclanrs Jan 05 '17 at 19:15
  • @elclanrs - that's silly: `var a = [3, 4]; for(i in a) { console.log(a[i]); }` – Madbreaks Jan 05 '17 at 19:16
  • @4castle Thanks, it looks like we have a culprit :) – S1awek Jan 05 '17 at 19:16
  • @elclanrs or [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of). – canon Jan 05 '17 at 19:17
  • @Madbreaks, don't think that's silly, it's the intent of the iteration that confuses people, and that's why thinking about it in those terms makes sense. – elclanrs Jan 05 '17 at 19:17
  • 1
    @elclanrs no I mean, it's silly to state that `for..in` is to blame here, or that it can't be used on arrays. Try it for yourself. – Madbreaks Jan 05 '17 at 19:19
  • Unless you're specifically trying to implement/practice arrays or loops, it might be worth looking into the `Date` object for this sort of logic. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date – sbeliv01 Jan 05 '17 at 19:19
  • @Madbreaks, I didn't say it was to blame, hence the comment, nor I did say it wasn't possible to use it with arrays, but that it is not meant to be used to loop arrays (as in the concept of an array of contiguous numeric indices). – elclanrs Jan 05 '17 at 19:20

2 Answers2

5

Your problem is likely the single = here:

for (elem1 in arr1) {
      if (arr1[elem1][1] = '01') {
                        ^^^

...which means your if always evaluates to true.

Madbreaks
  • 19,094
  • 7
  • 58
  • 72
0

Something like the following should work.

function makeFriendlyDates (arr) {

  // Splits each element of the array, and returns an array of results
  var splitArr = arr.map(function (el) {return el.split('-');});

  // Prefer console.log to printing to HTML
  // document.getElementById('result').innerHTML = splitArr;
  console.log(splitArr);

  var monthNames = ["January", "February", "March", "April", 
    "May", "June", "July", "August", "September", "October", 
    "November", "December"
  ];

  // See http://stackoverflow.com/a/1643468/1327983
  splitArr.forEach(function (el) {
    var month = monthNames[ parseInt(el[1])-1 ];
    // What do you want to do with it from here?
    el[1] = month;
  });

  // Demonstrate results
  console.log(splitArr);
}

makeFriendlyDates(['2016-07-01', '2016-08-04']);
alttag
  • 1,163
  • 2
  • 11
  • 29