Eloquent Javascript: Exercise: A list - javascript

I am learning JavaScript from a book called 'Eloquent Javascript'
I'm trying to solve the exercise described here: http://eloquentjavascript.net/04_data.html#h_nSTX34CM1M
I managed to work out that this code works:
function arrayToList(array) {
var list = null;
for (var i = array.length - 1; i >= 0; i--)
list = {
value: array[i],
rest: list
};
return list;
}
console.log(arrayToList([1, 2, 3]));
Result: { value: 1, rest: { value: 2, rest: { value: 3, rest: null } } }
So far, so good, and according to the book this is the right solution. BUT!
When I try to run the same thing but instead with a longer array, let's say:
console.log(arrayToList([1, 2, 3, 4, 5]));
The result is: { value: 1, rest: { value: 2, rest: { value: 3, rest: [Object] } } }
Why is this? Is my code wrong?

There's nothing wrong with a longer array. console.log() is a non-standard, browser-specific implementation and some implementations set a cap on how many levels of object nesting they will display. When they hit that level, they just display [Object] rather than recurse into it to show deeper nesting.
If you actually set a breakpoint and examine your variable in the debugger, you will see you can expand the nested levels as deep as it goes and see everything.
Or, you could do this:
console.log(JSON.stringify(arrayToList([1, 2, 3, 4, 5])));
to manually convert the whole thing to a string before using console.log() on it.

Related

How do you refer to an object within an object using index positions? Javascript

Say I have some objects like what's shown below. What I want to do is refer to the index positions in myObjects. For example, myObjects[0].parameter1 would be give me blue. However referencing stuff by index positions doesn't seem to work in objects. Am I just getting the syntax wrong or is this just not possible with javascript?
let myObjects= {
objectA:{
parameter1: blue,
parameter2: 5,
},
object B:{
parameter1: orange,
parameter2: 4,
},
}
Updated post below
let myObjects = [
{
parameter1: 'blue',
parameter2: 5,
},
{
parameter1: 'orange',
parameter2: 4,
},
]
let obj = myObjects.find(o => o.parameter1 === 'blue');
console.log(obj)
I also included how you can find that object with a specific parameter, in this case blue and then return it to a variable. Obviously im just console logging the object, but you can use it for whatever you want.

Undefined value with declared values JavaScript

So here's the problematic code
var board = [
{
grdNbr: 1,
value: 0,
},
{
grdNbr: 2,
value: 0,
},
{
grdNbr: 3,
value: 0,
},
{
grdNbr: 4,
value: 0,
},
{
grdNbr: 5,
value: 0,
},
{
grdNbr: 6,
value: 0,
},
{
grdNbr: 7,
value: 0,
},
{
grdNbr: 8,
value: 0,
},
{
grdNbr: 9,
value: 0,
},
]
I tried declaring objects as arrays, but I don't really get how it works, so please explain it to me. So, back to the topic. When I check the value it shows undefined (the code is below)
switch(board.grdNbr){
case 1:
board.value = 1
console.log(board.value)
bg.bg1 = x
msg.channel.send(boardDRW)
turn++
break;
...
}
After that, in the console log the value for value is 1, but before that the value is undefined. Any idea how can I fix this?
Your problem is your board variable is an array of object, and you try to access directly a parameter of the array without specifying what object of the array you wanna access.
Instead of trying to access a value with board.value, you should use board[index].value with index being the index of the object in that list (exemple : board[0].value)
Before I begin, I want to thank you that you spent some time helping me out. I found a solution to my problem with a different code, so I'm very sorry for wasting your time.
Have a nice day!
Abyzls

Making a function returning assorted arrays?

I am trying to define a function, merge, which, when given two sorted arrays containing numbers, returns a sorted array of the numbers from both lists.
merge([ 4, 5, 6 ], [ 1, 2, 3, 4 ]) => [ 1, 2, 3, 4, 4, 5, 6 ]
merge([ 4 ], [ 2, 5, 8 ]) => [ 2, 4, 5, 8 ]
merge([ 1, 2, 6 ], []) => [ 1, 2, 6 ]
This is my code:
function merge(arr1, arr2) {
return arr1.concat(arr2).sort(arr1, arr2);
}
While the output is correct, I am told -- from my studies, and its automated tests -- that this code is not in good style. It writes:
Does not handles two arrays of same length.
Doesn't handle shorter first array.
Doesn't handle shorter second array.
What is a better way I can write this code? What should I do better?
Your code looks ok, however the way you're using sort is incorrect.
One way to use sort is to supply a function that compares two values in the array, and returns a number (positive or negative) to dictate the sorting of those values. For more information on sort, see this article
Consider the following changes to your merge method:
function merge(arr1, arr2) {
return arr1.concat(arr2).sort(function(valueA, valueB) { return valueA - valueB; );
}
Other answers already give you the literal answer of how to make your code correct. However, it is possibly missing the point. The function that you described is used in building a "merge sort", a very important sorting algorithm, whose major advantage is that it only needs to read the input lists once, sequentially, resulting in complexity of O(N) per pass; this allows it to even sort things that can't fit into the memory. Your code does not do that - it relies on sort, which is O(N log(N)) each time you invoke your function, and it doesn't utilise the fact that both its inputs are already pre-sorted (which is a key requirement for merge sort).
The merge sort algorithm will take the first element from both lists, then append the smaller one. Then it compares the next element from that list with the other list's first element, and again takes the smaller one. Repeat until one list is exhausted, then append the rest of the surviving list. (You can find a more exhaustive explanation of the merge sort on the Wikipedia page).
Amadan's answer paid attention to the problem constraints and pointed out that this can be written in O(n) time. Essentially, when inputs are both sorted, the algorithm is the "merge" step in a merge sort. This is done in linear time and works in a very simple and pleasing manner: look at the first item of each list and take the smaller of the two until one or both lists are exhausted. Then, tack any remaining elements onto the result array and return it.
The other answers are fine and in good JS style, but are in O(n log n) time and ignore entirely that the arrays are pre-sorted without mention, which is almost certainly not the answer someone asking for this routine would be looking for.
Here's a merge step:
const merge = (a, b) => {
const result = [];
while (a.length && b.length) {
result.push(a[0] < b[0] ? a.shift() : b.shift());
}
return result.concat(a).concat(b);
};
console.log(merge([ 4, 5, 6 ], [ 1, 2, 3, 4 ])); // => [ 1, 2, 3, 4, 4, 5, 6 ]
console.log(merge([ 4 ], [ 2, 5, 8 ])); // => [ 2, 4, 5, 8 ]
console.log(merge([ 1, 2, 6 ], [])); // => [ 1, 2, 6 ]
This can also be done with indexes which preserves the original arrays and is faster, but a little uglier-looking.
Here's a benchmark at JSPerf.
Just concat the arrays and return after applying a simple sort function:
console.log(merge([4, 5, 6], [1, 2, 3, 4])); //[ 1, 2, 3, 4, 4, 5, 6 ]
console.log(merge([4], [2, 5, 8])); //[ 2, 4, 5, 8 ]
console.log(merge([1, 2, 6], [])); //[ 1, 2, 6]
function merge(a, b) {
return a.concat(b).sort((a, b) => a - b);
}

Why doesn't my linked list output pass this test?

I'm taking a coding challenge for linked lists in javascript. I haven't written a solution because I'm still trying to understand the basics.
Here's one of about 20 tests:
Input:
l: [3, 1, 2, 3, 4, 5]
k: 3
Expected Output:
[1, 2, 4, 5]
As a sort of hack to make sure I'm doing this right, I tried running the tests with this
function removeKFromList(l, k) {
return { value: 1, next: { value: 2, next: { value: 4, next: { value: 5, next: null}}}};
}
Returning a linked list... but it doesn't pass. Then I simply returned the array
function removeKFromList(l, k) {
return [1,2,4,5]
}
and it passed the first test.
Here's the question:
"Given a singly linked list of integers l and an integer k, remove all elements from list l that have a value equal to k."
My question is: Does l = [3, 1, 2, 3, 4, 5] count as a "linked list of integers"?
No, it doesn't, it's an array. However, it seems they're just giving the seed data, to leave the implementation (if you want) of the specifics of the linked list (along with seeding it) up to you completely. With that, means they need a uniform return which would be a 'seed' back to them (an array in order)

Delete Object From A Value

I have a object, in that object I have other objects (objectseption). Now I want to be able to delete one of those objects (the objects within the main object) from a ID value given. I'll show you what I mean:
object {
1 : {
id: 1,
name: john
},
2: {
id: 3,
name: sam
},
3: {
id: 5,
name: ollie
},
4: {
id: 12,
name: nathan
}
}
Now let's say that I want to delete/remove Sam from the object, but all I have is Sam's ID. This is where I'm stuck. How do I remove Sam only having his ID (which is 3).
I'm quite new to javascript, and usually rely heavily on frameworks to complete a project - so when it comes to these simple things I get quite stuck!
Any Help would be greatly appreciated!
Iterate the objects properties, check, and remove:
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key].id == 3) {
delete obj[key];
}
}
}

Categories