Array.map doesn't seem to work on uninitialized arrays [duplicate]

Asked
Active3 hr before
Viewed126 times

7 Answers

doesn
90%

I'm trying to set default values on an uninitialized array using the map function but it doesn't seem to work, any ideas on how to set default values?,The .map() function skips entries that have never been assigned values. Thus on a newly-constructed array like yours, it does essentially nothing., I ran into this problem and it actually does work on undefined values, (undefined as in the javascript type), just not on uninitialized values. – xor May 29 '20 at 14:14 ,I was expecting the array to be initialized to 0's.

If you'd like to fill an array, you can use Array(5).fill() and the methods will then work as expected--see the alternate related answer from aasha7. Older pre-fill approaches include:

Array.apply(null, new Array(5)).map(function() {
   return 0;
});
// [ 0, 0, 0, 0, 0 ]

After some reading one of the posts linked in the comments, I found this can also be written as

Array.apply(null, {
   length: 5
}).map(function() {
   return 0;
});

However, trying to use .map on undefined values will not work.

x = new Array(10);
x.map(function() {
   console.log("hello");
});

// so sad, no "hello"
// [ , , , , , , , , ,  ]
load more v
88%

I'm trying to set default values on an uninitialized array using the map function but it doesn't seem to work, any ideas on how to set default values?,The .map() function skips entries that have never been assigned values. Thus on a newly-constructed array like yours, it does essentially nothing.,Since there is no initilized member in your array, calling e.g new Array (1337).hasOwnProperty (42)evaluates to false, hence the condition in step 8.c is not met.,If you'd like to fill an array, you can use Array(5).fill() and the methods will then work as expected--see the alternate related answer from aasha7. Older pre-fill approaches include:

Consider this code snippet I tried in Chrome console.

>
var N = 10; >
var x = new Array(N); >
x
   [undefined x 10]

   >
   x.map(function(i) {
      return 0;
   });
[undefined x 10]
load more v
72%

a non-existing object property movie.year,an uninitialized variable number,Use let declaration for variables whose value can change. Whenever possible assign an initial value right away, e.g. let index = 0.,The same uninitialized concept happens when a non-existing object property is accessed:

The short answer is that JavaScript interpreter returns undefined when accessing a variable or object property that is not yet initialized. For example:

javascriptlet company;
company; // => undefinedlet person = { name: 'John Smith' };person.age; // => undefined
load more v
65%

A new array with each element being the result of the callback function.,Value to use as this when executing callbackFn., The map() method creates a new array populated with the results of calling a provided function on every element in the calling array. ,The callbackFn function accepts the following arguments:

// Arrow function
map((element) => {
   ...
})
map((element, index) => {
   ...
})
map((element, index, array) => {
   ...
})

// Callback function
map(callbackFn)
map(callbackFn, thisArg)

// Inline callback function
map(function callbackFn(element) {
   ...
})
map(function callbackFn(element, index) {
   ...
})
map(function callbackFn(element, index, array) {
   ...
})
map(function callbackFn(element, index, array) {
   ...
}, thisArg)
load more v
75%

Array elements are treated just like normal variables, and as such, they are not initialized when created.,One way to “initialize” an array is to do it element by element:,Initializing fixed arrays,If the initializer list is omitted, the elements are uninitialized, unless they are a class-type.

One way to “initialize” an array is to do it element by element:

int prime[5]; // hold the first 5 prime numbers
prime[0] = 2;
prime[1] = 3;
prime[2] = 5;
prime[3] = 7;
prime[4] = 11;
int prime[5] {
   2,
   3,
   5,
   7,
   11
}; // use initializer list to initialize the fixed array

The following example shows this in action:

#include <iostream>

int main()
{
    int array[5]{ 7, 4, 5 }; // only initialize first 3 elements

    std::cout << array[0] << '\n';
    std::cout << array[1] << '\n';
    std::cout << array[2] << '\n';
    std::cout << array[3] << '\n';
    std::cout << array[4] << '\n';

    return 0;
}

This prints:

7
4
5
0
0

Consequently, to initialize all the elements of an array to 0, you can do this:

// Initialize all elements to 0
int array[5] {};

// Initialize all elements to 0.0
double array[5] {};

// Initialize all elements to an empty string
std::string array[5] {};
// uninitialized
int array[5];

// uninitialized
double array[5];

// Initialize all elements to an empty string
std::string array[5];

The following two lines are equivalent:

int array[5] {
   0,
   1,
   2,
   3,
   4
}; // explicitly define the length of the array
int array[] {
   0,
   1,
   2,
   3,
   4
}; // let the initializer list set length of the array

One of the big documentation problems with arrays is that integer indices do not provide any information to the programmer about the meaning of the index. Consider a class of 5 students:

constexpr int numberOfStudents {
   5
};
int testScores[numberOfStudents] {};
testScores[2] = 76;

This can be solved by setting up an enumeration where one enumerator maps to each of the possible array indices:

enum StudentNames {
   kenny, // 0
   kyle, // 1
   stan, // 2
   butters, // 3
   cartman, // 4
   max_students // 5
};

int main() {
   int testScores[max_students] {}; // allocate 5 integers
   testScores[stan] = 76;

   return 0;
}

In this way, it’s much clearer what each of the array elements represents. Note that an extra enumerator named max_students has been added. This enumerator is used during the array declaration to ensure the array has the proper length (as the array length should be one greater than the largest index). This is useful both for documentation purposes, and because the array will automatically be resized if another enumerator is added:

enum StudentNames {
   kenny, // 0
   kyle, // 1
   stan, // 2
   butters, // 3
   cartman, // 4
   wendy, // 5
   max_students // 6
};

int main() {
   int testScores[max_students] {}; // allocate 6 integers
   testScores[stan] = 76; // still works

   return 0;
}

Enum classes don’t have an implicit conversion to integer, so if you try the following:

enum class StudentNames {
   kenny, // 0
   kyle, // 1
   stan, // 2
   butters, // 3
   cartman, // 4
   wendy, // 5
   max_students // 6
};

int main() {
   int testScores[StudentNames::max_students] {}; // allocate 6 integers
   testScores[StudentNames::stan] = 76;

   return 0;
}
int main()
{
    int testScores[static_cast<int>(StudentNames::max_students)]{}; // allocate 6 integers
    testScores[static_cast<int>(StudentNames::stan)] = 76;

    return 0;
}

However, doing this is somewhat of a pain, so it might be better to use a standard enum inside of a namespace:

namespace StudentNames {
   enum StudentNames {
      kenny, // 0
      kyle, // 1
      stan, // 2
      butters, // 3
      cartman, // 4
      wendy, // 5
      max_students // 6
   };
}

int main() {
   int testScores[StudentNames::max_students] {}; // allocate 6 integers
   testScores[StudentNames::stan] = 76;

   return 0;
}
#include <iostream>

void passValue(int value) // value is a copy of the argument
{
    value = 99; // so changing it here won't change the value of the argument
}

void passArray(int prime[5]) // prime is the actual array
{
    prime[0] = 11; // so changing it here will change the original argument!
    prime[1] = 7;
    prime[2] = 5;
    prime[3] = 3;
    prime[4] = 2;
}

int main()
{
    int value{ 1 };
    std::cout << "before passValue: " << value << '\n';
    passValue(value);
    std::cout << "after passValue: " << value << '\n';

    int prime[5]{ 2, 3, 5, 7, 11 };
    std::cout << "before passArray: " << prime[0] << " " << prime[1] << " " << prime[2] << " " << prime[3] << " " << prime[4] << '\n';
    passArray(prime);
    std::cout << "after passArray: " << prime[0] << " " << prime[1] << " " << prime[2] << " " << prime[3] << " " << prime[4] << '\n';

    return 0;
}
before passValue: 1
after passValue: 1
before passArray: 2 3 5 7 11
after passArray: 11 7 5 3 2

As a side note, if you want to ensure a function does not modify the array elements passed into it, you can make the array const:

// even though prime is the actual array, within this function it should be treated as a constant
void passArray(const int prime[5]) {
   // so each of these lines will cause a compile error!
   prime[0] = 11;
   prime[1] = 7;
   prime[2] = 5;
   prime[3] = 3;
   prime[4] = 2;
}

Here’s an example:

#include <iostream>
#include <iterator> // for std::size

int main()
{
    int array[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
    std::cout << "The array has: " << std::size(array) << " elements\n";

    return 0;
}

This prints:

The array has: 8 elements

Note that due to the way C++ passes arrays to functions, this will not work for arrays that have been passed to functions!

#include <iostream>
#include <iterator>

void printSize(int array[])
{
    std::cout << std::size(array) << '\n'; // Error
}

int main()
{
    int array[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
    std::cout << std::size(array) << '\n'; // will print the size of the array
    printSize(array);

    return 0;
}

The sizeof operator can be used on arrays, and it will return the total size of the array (array length multiplied by element size).

#include <iostream>

int main()
{
    int array[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
    std::cout << sizeof(array) << '\n'; // will print the size of the array multiplied by the size of an int
    std::cout << sizeof(int) << '\n';

    return 0;
}
32
4

One neat trick: we can determine the length of a fixed array by dividing the size of the entire array by the size of an array element:

#include <iostream>

int main()
{
    int array[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
    std::cout << "The array has: " << sizeof(array) / sizeof(array[0]) << " elements\n";

    return 0;
}

This printed

The array has: 8 elements

When sizeof is used on an array that has been passed to a function, it doesn’t error out like std::size() does. Instead, it returns the size of a pointer.

#include <iostream>

void printSize(int array[])
{
    std::cout << sizeof(array) / sizeof(array[0]) << '\n';
}

int main()
{
    int array[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
    std::cout << sizeof(array) / sizeof(array[0]) << '\n';
    printSize(array);

    return 0;
}

Again assuming 8 byte pointers and 4 byte integers, this prints

8
2

Consider the following program:

int main() {
   int prime[5] {}; // hold the first 5 prime numbers
   prime[5] = 13;

   return 0;
}
double temperature[365] {
   0.0
};
#include <iostream>

namespace Animals
{
    enum Animals // The name of this enum could be omitted since it isn't used anywhere
    {
        chicken,
        dog,
        cat,
        elephant,
        duck,
        snake,
        max_animals
    };
}

int main()
{
    int legs[Animals::max_animals]{ 2, 4, 4, 4, 2, 0 };

    std::cout << "An elephant has " << legs[Animals::elephant] << " legs.\n";

    return 0;
}
load more v
40%

It is possible to iterate over an array of arrays and unpack the nested array into loop variables by providing a list() as the value. , It is possible to iterate a constant array's value by reference: , Alternative syntax for control structures , It is possible to customize object iteration.

foreach(iterable_expression as $value)
statement
foreach(iterable_expression as $key => $value)
statement
load more v
22%

Standard mathematical functions for fast operations on entire arrays of data without having to write loops,Tools for reading / writing array data to disk and working with memory-mapped files,For most data analysis applications, the main areas of functionality I’ll focus on are:,Fast vectorized array operations for data munging and cleaning, subsetting and filtering, transformation, and any other kinds of computations

In[13]: data1 = [6, 7.5, 8, 0, 1]

In[14]: arr1 = np.array(data1)

In[15]: arr1
Out[15]: array([6., 7.5, 8., 0., 1.])
In[16]: data2 = [
   [1, 2, 3, 4],
   [5, 6, 7, 8]
]

In[17]: arr2 = np.array(data2)

In[18]: arr2
Out[18]:
   array([
      [1, 2, 3, 4],
      [5, 6, 7, 8]
   ])

In[19]: arr2.ndim
Out[19]: 2

In[20]: arr2.shape
Out[20]: (2, 4)
In[21]: arr1.dtype
Out[21]: dtype('float64')

In[22]: arr2.dtype
Out[22]: dtype('int64')
In[23]: np.zeros(10)
Out[23]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

In[24]: np.zeros((3, 6))
Out[24]:
   array([
      [0., 0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0., 0.]
   ])

In[25]: np.empty((2, 3, 2))
Out[25]:
   array([
      [
         [4.94065646e-324, 4.94065646e-324],
         [3.87491056e-297, 2.46845796e-130],
         [4.94065646e-324, 4.94065646e-324]
      ],

      [
         [1.90723115e+083, 5.73293533e-053],
         [-2.33568637e+124, -6.70608105e-012],
         [4.42786966e+160, 1.27100354e+025]
      ]
   ])
In[26]: np.arange(15)
Out[26]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
load more v

Other "doesn-undefined" queries related to "Array.map doesn't seem to work on uninitialized arrays [duplicate]"