How to override the nested array object - javascript

I would like to know how to overwrite the values in an object array if exists else merge the objects using Javascript.
For example, targetAmount matches in parent, so I need to override the matched value and remaining values just insert the parent object.
var my_obj = [{
description: "transferwise_description"
fee: "0.5"
id: "transferwise"
logo: "transferwiselogo.png"
name: "Transferwise"
speed: "1 Days"
targetAmount: "2000"
}]
var tomerge_obj = {
rate: 51.00674
source: "SGD"
sourceAmount: 1000
target: "INR"
targetAmount: 50688.97
type: "REGULAR"
}
Expected Output
var merged_object = [{
description: "transferwise_description"
fee: "0.5"
id: "transferwise"
logo: "transferwiselogo.png"
name: "Transferwise"
speed: "1 Days"
rate: 51.00674
source: "SGD"
sourceAmount: 1000
target: "INR"
targetAmount: 50688.97
type: "REGULAR"
}]

You can do it in one line with Object.assign(). You can find more documentation on it here.
const result = Object.assign({}, my_obj[0], tomerge_obj);

You can simply use destructuring, this way:
var merged_object = {...my_obj[0], ...tomerge_obj}
It will return a new object with the values from tomerge_obj duplicated keys will replace the ones in the object inside my_obj.
You can also use Object.assign and assign both objects to an empty one to achieve the same result.

var my_obj = [{
description: "transferwise_description",
fee: "0.5",
id: "transferwise",
logo: "transferwiselogo.png",
name: "Transferwise",
speed: "1 Days",
targetAmount: "2000"
}];
var tomerge_obj = {
rate: 51.00674,
source: "SGD",
sourceAmount: 1000,
target: "INR",
targetAmount: 50688.97,
type: "REGULAR"
};
my_obj[0] = {...my_obj[0], ...tomerge_obj};
console.log(my_obj);
my_obj[0] = {...my_obj[0], ...tomerge_obj};
'...' is the spread operator and is commonly used for object de-structuring.
What this will essentially do is that it will reassign the first element of the array with the newly created object by spreading the attributes of the two objects.
The console.log will prove the assertion.

jQuery's extend is here just for that (answered this because you tagged jQuery, it has a much wider browser support than assign or spread operator)
Note that it modifies the original object, if you don't want, use var res = $.extend(true, {}, my_obj[0], tomerge_obj);
var my_obj= [
{
description: "transferwise_description",
fee: "0.5",
id: "transferwise",
logo: "transferwiselogo.png",
name: "Transferwise",
speed: "1 Days",
targetAmount: "2000",
}
];
var tomerge_obj = {
rate: 51.00674,
source: "SGD",
sourceAmount: 1000,
target: "INR",
targetAmount: 50688.97,
type: "REGULAR",
};
$.extend(true, my_obj[0], tomerge_obj)
console.log(my_obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

return charachetrs with the same key door

I have an array of objects(characters) where each object has an array of objects(keys), a door can be opened by multiple keys as you can see in this example
const characters = [
{ id: "1", type: "water", keys: [{ name: "key_786", door: "XOPR" }] },
{ id: "2", type: "fire", keys: [{ name: "key_23", door: "JTHF" }] },
{ id: "3", type: "wind", keys: [{ name: "key_987", door: "XOPR" }] },
];
What I want is to find all the characters that have a key that can open one specific door, for example I want to return all characters with keys.door === 'XOPR' how can I do it ?
I tried .filter .map but no luck, some help please ? I am new to react and javascript
you can use Array.prototype.some with Array.prototype.filter :
const result = characters.filter(ch => ch.keys.some(key => key.door === 'DOOR_NAME'));
First you filter through characters then for every one you loop through its keys property which is an array and for every item of this latter you chack if key.door === 'DOOR_NAME' so you return the character for this itteration(of the filter loop)

How do I incorporate the index of an array while defining a property of said array within a class in JavaScript?

Sorry if the title makes no sense.. let me explain
Say I have the following 2d array.. the first array representing ice cream and the second representing milkshakes
menu = [ ['vanilla', 'chocolate', 'almond'],
['vanilla', 'pineapple', 'strawberry'] ]
Now I create a class that takes this array as input
class cafe{
constructor(menu){
this.iceCreams = menu[0]
this.milkshakes = menu[1]
}
}
Now I want to define a property called 'price' for each flavor of milkshake.
this.milkshakes[n].price = < a function that computes price based on value of n >
so that i can access them like this :
cafe.milkshakes[0].price
So how do I incorporate the index 'n' of the array while defining the property
I haven't tried anything bcos I dont know how to even approach this ☹️
You can do it in your constructor.
You can grab the names, and call map function on it and do whatever you want. Please check the following example. There, calculatePrice is a function that takes the index and returns the price based on the index.
class Cafe {
constructor (menu) {
this.iceCreams = menu[0].map((flavor, index) => {
return {
flavor,
price: calculatePrice(index)
}
});
this.milkshakes = menu[1].map((flavor, index) => {
return {
flavor,
price: calculatePrice(index)
}
});
}
This is a minimal answer.
UPDATE:
For a detailed and improved answer: https://codesandbox.io/s/cafe-example-wxp2c4
So, in the milkshakes array you need each item as an object data structure, not a string.
menu = [ ['vanilla', 'chocolate', 'almond'],
[{ flavor: 'vanilla' }, { flavor: 'pineapple' }, { flavor: 'strawberry' }] ]
and then you can loop through and set the price, something like this.
menu.milkshakes.forEach((item, index) => item.price = index))
you can use objects:
menu = [
[
{
name: "vanilla",
price: 200,
},
{
name: "chocolate",
price: 200,
},
{
name: "almond",
price: 200,
},
],
[
{
name: "vanilla",
price: 200,
},
{
name: "pineapple",
price: 200,
},
{
name: "strawberry",
price: 200,
},
],
];
and then:
class cafe{
constructor(menu){
this.iceCreams = menu[0]
this.milkshakes = menu[1]
}
}
now iceCreams and milshakes have the property price and name
example:
iceCreams[n].price
iceCreams[n].name

how to get object length in pure javascript? [duplicate]

This question already has answers here:
How to efficiently count the number of keys/properties of an object in JavaScript
(19 answers)
Closed 11 months ago.
how to get object length in pure javascript in this code
let myFavGames = {
"Trinity Universe": {
publisher: "NIS America",
price: 40,
},
"Titan Quest": {
publisher: "THQ",
bestThree: {
one: "Immortal Throne",
two: "Ragnarök",
three: "Atlantis",
},
price: 50,
},
YS: {
publisher: "Falcom",
bestThree: {
one: "Oath in Felghana",
two: "Ark Of Napishtim",
three: "origin",
},
price: 40,
},
};
// Code One => How To Get Object Length ?
let objectLength = ?;
You can use Object.keys() to get the number of keys in your object:
const myFavGames = {
"Trinity Universe": {
publisher: "NIS America",
price: 40,
},
"Titan Quest": {
publisher: "THQ",
bestThree: {
one: "Immortal Throne",
two: "Ragnarök",
three: "Atlantis",
},
price: 50,
},
YS: {
publisher: "Falcom",
bestThree: {
one: "Oath in Felghana",
two: "Ark Of Napishtim",
three: "origin",
},
price: 40,
},
};
const objectLength = Object.keys(myFavGames).length;
console.log(objectLength); // 3
The Object.keys() method returns an array of a given object's own enumerable property names.
console.log(Object.keys(myFavGames).length);

Nested arrays with objects, lodash meanBy

Can someone please help me understand how to make this work. Everytime I feel like I start to understand arrays and objects in Javascript it turns out that I still don't.
I'm trying to get the average of all prices in the following datastructure by using lodash meanBy
[
{
date: "2019-12-17",
items: [
{ id: "1", state: "accepted", price: "90.5" },
{ id: "2", state: "rejected", price: "20.0" },
{ id: "3", state: "open", price: "10.5" },
]
},
{
date: "2019-12-18",
items: [
{ id: "4", state: "open", price: "450.0" },
{ id: "5", state: "rejected", price: "40.1" },
{ id: "6", state: "accepted", price: "50.9" },
]
}
]
If you provide the answer, can you also please try to explain how you select something nested in items, because that's as far as I get before I get lost.
In this case instead of selecting nested values, it's easier to flatten the items to a single array, and then apply _.meanBy(). In addition, the prices are strings, and not numbers, so you'll need to convert them.
Flatten the items to a single array with Array.flatMap(), and then use _.meanBy(), and get the numeric values of the prices:
const data = [{"date":"2019-12-17","items":[{"id":"1","state":"accepted","price":"90.5"},{"id":"2","state":"rejected","price":"20.0"},{"id":"3","state":"open","price":"10.5"}]},{"date":"2019-12-18","items":[{"id":"4","state":"open","price":"450.0"},{"id":"5","state":"rejected","price":"40.1"},{"id":"6","state":"accepted","price":"50.9"}]}]
const result = _.meanBy(_.flatMap(data, 'items'), o => +o.price)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Another approach is to get the general average, by getting the average of each items array separately , and then getting the average of all averages.
const data = [{"date":"2019-12-17","items":[{"id":"1","state":"accepted","price":"90.5"},{"id":"2","state":"rejected","price":"20.0"},{"id":"3","state":"open","price":"10.5"}]},{"date":"2019-12-18","items":[{"id":"4","state":"open","price":"450.0"},{"id":"5","state":"rejected","price":"40.1"},{"id":"6","state":"accepted","price":"50.9"}]}]
const result = _.meanBy(data, ({ items }) => _.meanBy(items, o => +o.price))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Search through an array of objects looking for non empty objects JS

At the core of the problem I have:
[
{amount: 0, name: "", icon: "", description: ""} // default object added to array
{amount: 1, name: "kjfhdkfjh", icon: "67", description: "dasdasd"}
]
I want to know how to use lodash find such that, as long as any key has a value other then 0 or "" we are not considered "empty".
So in this case lodash find would return:
[
{amount: 1, name: "kjfhdkfjh", icon: "67", description: "dasdasd"}
]
Or it would return undefined.
What I have is:
lodashFind(theArray, function(obj){
// Now what? How do I go through the objects?
});
I am not sure how to go through objects saying, as long as there is no 0 for amount and no string has "" then return that object.
Ideas?
Use _.filter, _.some, _.all or _.negate of lodash to achieve this:
var data = [
{ name:'a', age:0 },
{ name:'b', age:1 },
{ name:'', age:0 }
];
// lists not empty objects (with at least not empty field)
console.log(_.filter(data, _.some));
// outputs [{name:'a',age:0},{name:'b',age:1}]
// lists 'full' objects (with no empty fields)
console.log(_.filter(data, _.all));
// outputs [{name:'b',age:1}]
// lists 'empty' objects (with only empty fields)
console.log(_.filter(data, _.negate(_.some)));
// outputs [{name:'',age:0}]
_.some and _.all search for truthy values, '' and 0 is not truthy. Namely, the following JavaScript values are falsy: false, 0, '', null, undefined, NaN. Every other value is truthy.
Using just regular javascript, this is quite easy as well, just filter the array based on the objects values etc, like this
var arr = [
{amount: 0, name: "", icon: "", description: ""},
{amount: 1, name: "kjfhdkfjh", icon: "67", description: "dasdasd"}
]
arr = arr.filter(function(o) {
return Object.keys(o).filter(function(key) {
return o[key] != 0 && o[key].toString().trim().length > 0;
}).length > 0;
});
FIDDLE

Categories

Resources