nodejs/JS: Objects not being updated in array [duplicate] - javascript

This question already has answers here:
Push object in Javascript
(3 answers)
Closed 2 years ago.
Firstly, I am a complete noob to Javascript and Node.js.
I tried to write a simple program that creates an array of planes that all have the same values except in index, which should take on the value of each index in the for loop from 0 - 2.
Here is my code
var plane = {
index: -1,
name: "A380",
seats: {
first: 40,
buisness: 90,
economy: 300
},
wheels: 8,
}
var planeArray = []
for (var i = 0; i < 3; i++) {
plane.index = i
planeArray.push(plane)
}
console.log(planeArray)
But when I print the output, the indices of all the planes are 2. Here is my output.
[
{
index: 2,
name: 'A380',
seats: { first: 40, buisness: 90, economy: 300 },
wheels: 8
},
{
index: 2,
name: 'A380',
seats: { first: 40, buisness: 90, economy: 300 },
wheels: 8
},
{
index: 2,
name: 'A380',
seats: { first: 40, buisness: 90, economy: 300 },
wheels: 8
}
]
Here is my expected output.
[
{
index: 0,
name: 'A380',
seats: { first: 40, buisness: 90, economy: 300 },
wheels: 8
},
{
index: 1,
name: 'A380',
seats: { first: 40, buisness: 90, economy: 300 },
wheels: 8
},
{
index: 2,
name: 'A380',
seats: { first: 40, buisness: 90, economy: 300 },
wheels: 8
}
]
I don't understand why.
Could someone help me out. Also, any additional explanations/resources helpful for learning node.js would be greatly appreciated

The problem here is that the object being added in the array goes as a reference and not as the value of the object
you can either try either of the below two solutions.
This way you pass the object value instead of its reference.
for (var i = 0; i < 3; i++) {
plane.index = i
planeArray.push({...plane})
}
for (var i = 0; i < 3; i++) {
plane.index = i
planeArray.push(JSON.parse(JSON.stringify(plane)))
}

You are always changing the same object with plane.index = i. If you want to have three different entries in your array you need three different objects.

Related

Create object of objects from arrays [duplicate]

This question already has answers here:
How to combine two arrays into an array of objects? [duplicate]
(2 answers)
Closed 7 months ago.
I have two arrays in JavaScript:
a = [2, 5, 8, 10, 12, 15]
and
b = ["2022-01-01", "2022-01-02", "2022-01-03", "2022-01-04", "2022-01-05", "2022-01-06"]
I want to turn this into an object of objects, like so:
ts = {
{
value: 2,
time: "2022-01-01"
},
{
value: 5,
time: "2022-01-02"
},
{
value: 8,
time: "2022-01-03"
},
{
value: 10,
time: "2022-01-04"
},
{
value: 12,
time: "2022-01-05"
},
{
value: 15,
time: "2022-01-06"
}
}
I have looked at the forEach method and the reduce method, e.g. from https://bobbyhadz.com/blog/javascript-create-object-from-two-arrays , but I am struggling. Edit: my attempt was along the lines of:
const ts = {};
a.forEach((a_value, index) => {
ts.value[index] = a_value[index];
});
A simple for loop will work if both lists are the same size.
let a = [2, 5, 8, 10, 12, 15]
let b = ["2022-01-01", "2022-01-02", "2022-01-03", "2022-01-04", "2022-01-05", "2022-01-06"]
let ts = []
for (let idx in a) {
ts.push({value: a[idx],
time: b[idx]})
}
console.log(ts)

How to create arrays based on array of objects value?

I'm working on a task where I've to make arrays based on certain values in array of objects.
Input Array:
const array = [{
name: 'A',
age: points: { x: 100, y: 107}
},
{
name: 'B',
age: points: { x: 210, y: 107}
},
{
name: 'C',
age: points: { x: 110, y: 107}
},
{
name: 'D',
age: points: { x: 230, y: 107}
}
];
Expected Output:
[
[
{
name: 'A',
age: points: { x: 100, y: 107}
},
{
name: 'C',
age: points: { x: 110, y: 107}
}
],
[
{
name: 'B',
age: points: { x: 210, y: 107}
},
{
name: 'D',
age: points: { x: 230, y: 107}
}
]
]
Note: here condition value will be dynamic, for example, the points following under certain conditions can be fall in one array, if that out of condition then-new array will be formed and so on, there may be 200+ objects in the array.
In case new object occur as
{
name: 'D',
age: points: { x: 230, y: 107}
}
then a new array of object ll be formed and all objects falling in that condition should get added to that.
Please put your valuable suggestions.
Thanks in advance.
Your question isn't completely clear. From what I can guess, you have an array of objects, you need to store an empty result array. Then, consume the "dynamic conditions" one by one, use a filter method on the original array and keep adding the results on to the result array.
Here's some pseudocode:
let dataArray = [<your objects>];
let resultArray = [];
while(<dynamic condtions list is not empty>)
{
resultArray.push(dataArray.filter(item=>{
// write your filter logic based on your current dynamic condition here
if(item satisifes condition)
return true;
else
return false;
}))
}
console.log(resultArray);

Get every fourth of array and check between

I have array like this:
let arr = [
{ x: 31, y: 8 }, // get 1
{ x: 32, y: 8, monster: { is: true, id: '19216' } }, // get special
{ x: 32, y: 9 },
{ x: 32, y: 10 },
{ x: 32, y: 11 }, // get 4
{ x: 32, y: 12 },
{ x: 32, y: 13 },
{ x: 32, y: 14 },
{ x: 32, y: 15 }, // get 8
{ x: 32, y: 16 } // get last
];
what I want to achieve is to get every fourth, get special one (the one with monster object) and also last one. So the output would be
[
{x: 31, y: 8},
{x: 32, y: 8, monster: { is: true, id: '19216' } },
{x: 32, y: 11},
{x: 32, y: 15},
{x: 32, y: 16}
]
It was easy to get every fourth and last one like this:
let arrThinned = [];
for (let i = 0; i < arr.length; i = i + 4) {
arrThinned.push({
x: arr[i].x,
y: arr[i].y,
});
}
if((arr.length - 1) % 4 !== 0) {
/* add also last one if not already added */
arrThinned.push({
x: arr[arr.length - 1].x,
y: arr[arr.length - 1].y
});
};
but I can't figure out how to additionally check if there is this special one beetwen every fourth and also add it to thinnedArr array. I need to keep the order. Demo of above code.
Here, use filter
let arr = [
{ x: 31, y: 8 }, // get 1
{ x: 32, y: 8, monster: { is: true, id: '19216' } }, // get special
{ x: 32, y: 9 },
{ x: 32, y: 10 },
{ x: 32, y: 11 }, // get 4
{ x: 32, y: 12 },
{ x: 32, y: 13 },
{ x: 32, y: 14 },
{ x: 32, y: 15 }, // get 8
{ x: 32, y: 16 } // get last
];
let newArr = arr.filter((e,i,ar) => (i%4 === 0 || e.monster || i===ar.length-1));
console.log(newArr);
Used .flatMap() to sort out all required objects. A custom function based on this answer counts how many keys each object had so that if an object had more than 2 keys it was considered special.The version in demo is streamlined into one line.
/** objSize(object)
Utility that returns a given Object's number of non-enumerated property keys it
has (String and Symbol).
*/
const objSize = obj => {
let strings = Object.getOwnPropertyNames(obj).length;
let symbols = Object.getOwnPropertySymbols(obj).length;
return strings + symbols;
}
Further details about .flatMap() are commented in demo.
let array = [
{ x: 31, y: 8 }, // get 1
{ x: 32, y: 8, z: { is: true, id: '19216' } },
{ x: 32, y: 9 },
{ x: 32, y: 10 },
{ x: 32, y: 11 }, // get 4
{ x: 32, y: 12 },
{ x: 32, y: 13 },
{ x: 32, y: 14 },
{ x: 32, y: 15 }, // get 8
{ x: 32, y: 16 } // get last
];
const objSize = obj => Object.getOwnPropertyNames(obj).length + Object.getOwnPropertySymbols(obj).length;
/*
.flatMap() is an array method that is basically a
combonation of `.map()` and `.flat()`. Here it is running
a function of 4 ternary controls:
1. if current index is 0:
(idx === 0)
return [xy]
2. if current index is a factor of 4:
(idx % 4 === 0)
return [xy]
3. if current xy has more than 2 keys:
(objSize(xy) > 2)
return [xy]
4. if current index is the last:
(idx === array.length - 1)
return [xy]
5. otherwise return []
each return is an array which is flattened when the final
array is returned. Therefore an empty array is a clean
removal which means no nulls, spaces, or empty values.
*/
let result = array.flatMap((xy, idx) => xy === 0 ? [xy] : idx % 4 === 0 ? [xy] : objSize(xy) > 2 ? [xy] : idx === array.length - 1 ? [xy] : []);
console.log(JSON.stringify(result));

Javascript Knapsack Algorithm - find by lowest value

I have found an implementation of Knapsack problem. As you probably all know this algorithm is designed to find solution with the highest value of items that fits in backpack. I want to make it finds solution with the lowest values.
Here is the code:
var data= [
{name: 'map', weight: 9, value:150, pieces:1},
{name: 'compass', weight: 13, value: 35, pieces:1},
{name: 'water', weight:153, value:200, pieces:2},
{name: 'sandwich', weight: 50, value: 60, pieces:2},
{name: 'glucose', weight: 15, value: 60, pieces:2},
{name: 'tin', weight: 68, value: 45, pieces:3},
{name: 'banana', weight: 27, value: 60, pieces:3},
{name: 'apple', weight: 39, value: 40, pieces:3},
{name: 'cheese', weight: 23, value: 30, pieces:1},
{name: 'beer', weight: 52, value: 10, pieces:3},
{name: 'suntan, cream', weight: 11, value: 70, pieces:1},
{name: 'camera', weight: 32, value: 30, pieces:1},
{name: 'T-shirt', weight: 24, value: 15, pieces:2},
{name: 'trousers', weight: 48, value: 10, pieces:2},
{name: 'umbrella', weight: 73, value: 40, pieces:1},
{name: 'waterproof, trousers', weight: 42, value: 70, pieces:1},
{name: 'waterproof, overclothes',weight: 43, value: 75, pieces:1},
{name: 'note-case', weight: 22, value: 80, pieces:1},
{name: 'sunglasses', weight: 7, value: 20, pieces:1},
{name: 'towel', weight: 18, value: 12, pieces:2},
{name: 'socks', weight: 4, value: 50, pieces:1},
{name: 'book', weight: 30, value: 10, pieces:2}
];
function findBestPack() {
var m= [[0]]; // maximum pack value found so far
var b= [[0]]; // best combination found so far
var opts= [0]; // item index for 0 of item 0
var P= [1]; // item encoding for 0 of item 0
var choose= 0;
for (var j= 0; j<data.length; j++) {
opts[j+1]= opts[j]+data[j].pieces; // item index for 0 of item j+1
P[j+1]= P[j]*(1+data[j].pieces); // item encoding for 0 of item j+1
}
for (var j= 0; j<opts[data.length]; j++) {
m[0][j+1]= b[0][j+1]= 0; // best values and combos for empty pack: nothing
}
for (var w=1; w<=400; w++) {
m[w]= [0];
b[w]= [0];
for (var j=0; j<data.length; j++) {
var N= data[j].pieces; // how many of these can we have?
var base= opts[j]; // what is the item index for 0 of these?
for (var n= 1; n<=N; n++) {
var W= n*data[j].weight; // how much do these items weigh?
var s= w>=W ?1 :0; // can we carry this many?
var v= s*n*data[j].value; // how much are they worth?
var I= base+n; // what is the item number for this many?
var wN= w-s*W; // how much other stuff can we be carrying?
var C= n*P[j] + b[wN][base]; // encoded combination
m[w][I]= Math.max(m[w][I-1], v+m[wN][base]); // best value
choose= b[w][I]= m[w][I]>m[w][I-1] ?C :b[w][I-1];
}
}
}
var best= [];
for (var j= data.length-1; j>=0; j--) {
best[j]= Math.floor(choose/P[j]);
choose-= best[j]*P[j];
}
I have tried several things, but it didn't work for me, can you guys help me out?
Algorithm finds items that fits in container that has 400 capacity so it can contain items that has no more than 400 weight. It also try to fits items that have the best value. For example if 1 item has 10 weight and 5 value algorithm will take this item instead of item with 10 weight and 4 value. I want to make it reverse when it comes to value so algorithm will pick the item with 4 value instead of 5.
In general, the solution to the vanilla Knapsack problem for lowest values is trivial: you can simply choose to take nothing. If you're talking about lowest value for a certain weight threshold, then here's a hint: try negating all your values. In this case, the highest value knapsack is the least negative.

JavaScript filter array function

I've made a list of ships that it represented like so:
var fleet =
["RMS MARY", 2000, 15],
["TITANIC 2", 10000, 13],
["Boaty McBoatface", 2000, 18],
["Jutlandia", 1945, 10],
["Hjejlen", 250, 8]
];
I want to write a function that will filter the ships by a given capacity.
Example:
filterByCapacity(fleet,5000)
This should only return the ship Titanic 2 since it is the only ship with a capacity higher than 5000.
Any ideas on how to write such a function?
Easy :
function filterByCapacity(fleet, capacity) {
var filteredArray = [];
for (var i = 0; i < fleet.length; i++) {
// Supposing we know that the capacity is the second index in the array
if (fleet[i][1] >= capacity) // Or you can make this strictly greather than (>)
filteredArray.push(fleet[i]);
}
return (filteredArray);
}
But I suggest you use objects rather than arrays. Something more like this :
var fleet = [
{
name: "RMS MARY",
capacity: 2000,
age: 15, // I had no idea what the third index meant so I made up one
},
{
name: "TITANIC 2",
capacity: 10000,
age: 13,
},
{
name: "Boaty McBoatface",
capacity: 2000,
age: 18,
},
{
name: "Jutlandia",
capacity: 1945,
age: 10,
},
{
name: "Hjejlen",
capacity: 250,
age: 8,
}
];
That way you can make one generic function filterBy(fleet, paramName, paramValue) that could return you the ships that match the filter
First, I'd like to point out that your array was badly made. You were missing a left square bracket on the first entry ("RMS MARY".) The corrected array is below:
var fleet = [
["RMS MARY", 2000, 15],
["TITANIC 2", 10000, 13],
["Boaty McBoatface", 2000, 18],
["Jutlandia", 1945, 10],
["Hjejlen", 250, 8],
];
Second, I'd recommend that you represent the ships with objects instead of arrays, so you'd have something like this:
var fleet = {
{name: "RMS MARY", capacity: 2000, somethingElse: 15},
{name: "TITANIC 2", capacity: 10000, somethingElse: 13},
{name: "Boaty McBoatface", capacity: 2000, somethingElse: 18},
{name: "Jutlandia", capacity: 1945, somethingElse: 10},
{name: "Hjejlen", capacity: 250, somethingElse: 8},
};
Now, as for the function you want, I'll provide two, one for the original array representation of ships, and one for the object representation:
//array representation
function filterByCapacity(fleet, capacity){
return fleet.filter(function(ship){
return ship[1] >= capacity;
});
}
//object representation
function filterByCapacity(fleet, capacity){
return fleet.filter(function(ship){
return ship.capacity >= capacity;
});
}
Hope this helps.
Represent your ships as objects:
var fleet = [
{name: "RMS Mary", capacity: 2000, whatever: 15},
...
];
Then you can use filter in a way that is readable and makes sense.
function filterByCapacity(fleetArr, minCapacity) {
return fleetArr.filter(function(ship) {
return ship.capacity > minCapacity;
});
}
console.log(filterByCapacity(fleet, 5000)) // only Titanic

Categories

Resources