4

Do I have just a bad version of ecma script or is this some stupid shit in JS in general? I want each sub array to be separate entities, not that same one for all. I assume the fill in just putting the same list in all of them? I honestly don't care I guess, replacing a sublist is fine too. Rather than editing each element separately. Saves ram in long run.

let arr = Array(5).fill(Array(1,2))
console.log(arr)
arr[0][0] = 3
console.log(arr)

[[1,2],[1,2],[1,2],[1,2],[1,2]]
[[3,2],[3,2],[3,2],[3,2],[3,2]]

Congratulations, you are my dev duck today.

Comments
  • 0
    let arr = Array(model.length).fill(null) // has to be not undefined

    arr.forEach(function(current,index){ arr[index] = [1, 2]})

    Can now assign to each part using multidimensional indexing.
  • 3
    You are assigning the same object to all the items in the array. It happens in every programming language, but I don't understand why when something happens in JavaScript then JavaScript sucks, but if it was C everyone would have said how smart C is.

    Btw, always use fill with "null" then map: Array(5).fill(null).map(x=>[1,2])
  • 1
    @crisz Yeah, I figured it out part way through the question. I dislike JS, so any chance I get...
  • 0
    @Demolishun yes but sometimes it's just about reading a doc, and believe me that ES5+ is more straightforward than any other programming language, python included. The "fill" API is pretty old, but the pattern is: it's never used to directly fill the array, but just to create something to iterate over
  • 0
    @crisz So you don't get tired of coding and just want to destroy the universe toward the end of the day?
  • 1
    @crisz btw, half the reason I come onto this platform is to troll JS devs.
  • 2
    @crisz in C you don't have references by default
  • 0
    @iiii I was just thinking about that:

    std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    std::fill(v.begin(), v.end(), -1);

    Each part of the vector is separate memory by default. I cannot make a vector with references at all. I would have to use pointers.
  • 1
    @Demolishun you can't make a vector of references because they cannot be undefined and must be defined at construction time, which will not work with a vector, because it just allocates some memory without proper initialization.
  • 1
    @iiii Well this is interesting:

    https://en.cppreference.com/w/cpp/...

    All sorts of crap in the std.
  • 1
    @Demolishun well, yes, you need some weird stuff to make it work
  • 0
    I use immer for everything these days
  • 0
    @crisz I agree with you that a lot of the JS sucks nonsense comes from stupid things like mixing types. In this case it's far less obvious. In C every array and struct is a pointer and has to be explicitly copied.
    In JS I did not even know this was possible on arrays. As I might also just be ignorant here I would like to do some further tests to see if JS is highly irregular here or business a usual.
  • 1
    @hjk101 I really don‘t want to defend JS but the behavior is really obvious here. Array is not a value type but a reference type. Just like it is in C# and Java. And also in C (kind of) because arrays are pointers.
    It‘s understandable because of performance reasons but it‘s a shit design conceptually.

    I love Swift for making arrays value types and having cow semantics so that performance is on par with reference types.
  • 1
    @Lensflare yeah, it's such a pain in the ass in C# when you actually need to copy an object, but there's no clone interface and no constructor that accepts the same type object.
  • 0
    @iiii because in C you don't have objects. But try do it with a struct
  • 0
    Grats to finding a JavaScript behaviour that actually isn't a quirk. Yes, reference types work in JavaScript just like in all other major languages...
  • 1
    I guess when they wrote Array.fill they had to decide if they wanted to deep copy objects/arrays or just fill with the same reference.
  • 0
    I learned a lot from this rant. Thank you!
Add Comment