Update value of object in array with values in other Array [duplicate] - javascript

This question already has answers here:
Update value of object with values in different array
(4 answers)
Closed 2 years ago.
I am trying to reproduce my original problem;
I have two arrays in react state Array 1 is an original array from Database and Array2 is an updated array is state.
Objective is to update only changed rates and not quantity (and other pararmters) back to the Database, hence i need to update the values of rates in object of Array1 with the values of the rates in object 2 for a the objects of Array1 matching with the objects in Array2.
Array1 = [{
id: 1,
name: IceCream,
details: [{ id: "12", name: "milk", quantity: "50", rate: "100" },
{ id: "13", name: "cream", quantity: "50", rate: "300" }]
},
{
id: 2,
name: Coffee,
details: [{ id: "14", name: "Coffee bean", quantity: "60", rate: "200" },
{ id: "15", name: "water", quantity: "60", rate: "300" }]
},
{
id: 3,
name: Tea,
details: [{ id: "16", name: "Tea leaf", quantity: "50", rate: "700" }]
}]
Array2 = [{
id: 1,
name: IceCream,
details: [{ id: "12", name: "milk", quantity: "50", rate: "500" },
{ id: "13", name: "cream", quantity: "50", rate: "700" }]
},
{
id: 2,
name: Coffee,
details: [{ id: "14", name: "Coffee bean", quantity: "60", rate: "800" },
{ id: "15", name: "water", quantity: "60", rate: "8000" }]
}]

You need to iterate over the objects in Array1 using .map, check if it exists in Array2 by id using .find. Then, iterate over the details and update the rate if it also exists in that of the second array:
let Array1 = [
{
id:1,
name: "IceCream",
details:[
{id:"12",name:"milk",quantity:"50",rate:"100"},
{id:"13",name:"cream",quantity:"50",rate:"300"}
]
},
{
id:2,
name:"Coffee",
details:[
{id:"14",name:"Coffee bean",quantity:"60",rate:"200"},
{id:"15",name:"water",quantity:"60",rate:"300"}
]
},
{
id:3,
name:"Tea",
details:[
{id:"16",name:"Tea leaf",quantity:"50",rate:"700"}
]
}
]
let Array2 = [
{
id:1,
name: "IceCream",
details:[
{id:"12",name:"milk",quantity:"50",rate:"500"},
{id:"13",name:"cream",quantity:"50",rate:"700"}
]
},
{
id:2,
name:"Coffee",
details:[
{id:"14",name:"Coffee bean",quantity:"60",rate:"800"},
{id:"15",name:"water",quantity:"60",rate:"8000"}
]
}
]
Array1 = Array1.map(item => {
let element = Array2.find(e => e.id == item.id);
if(element){
item.details = item.details.map(e => {
let detail = element.details.find(d => d.id==e.id);
if(detail)
e.rate = detail.rate;
return e;
});
}
return item;
});
console.log(Array1);

Related

JS - manipulate variables on Object.assign

How can I manipulate variables inside - map.set(key, Object.assign({}, item));.
Array for example -
const arr = [
{
name: "daniel",
sum: "$100",
},
{
name: "daniel",
sum: "100",
},
{
name: "daniel",
sum: "$100",
},
{
name: "daniel",
sum: "100",
},
];
desired output -
const arr = [
{
name: "daniel",
sum: "100",
},
{
name: "daniel",
sum: "100",
},
{
name: "daniel",
sum: "100",
},
{
name: "daniel",
sum: "100",
},
];
How can I split for the example inside the assign?

Update object value in array with values in other array using hashtables or hashmap

I have two arrays Array1 and Array2, i am updating rate of object in Array1 with rate of same object (With same ID) in Array 2. I have a functions that loops through both arrays to get desired result. After going through some of the answers on Stack overflow I feel Hash table is best suited to reduce the complexity. I was just curious to understand how same can be implemented using the has maps.
let Array1 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "100"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "300"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "200"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "300"
}
]
},
{
id: 3,
name: "Tea",
details: [{
id: "16",
name: "Tea leaf",
quantity: "50",
rate: "700"
}]
}
]
let Array2 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "500"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "700"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "800"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "8000"
}
]
}
]
Array1 = Array1.map(item => {
let element = Array2.find(e => e.id == item.id);
if (element) {
item.details = item.details.map(e => {
let detail = element.details.find(d => d.id == e.id);
if (detail)
e.rate = detail.rate;
return e;
});
}
return item;
});
console.log(Array1);
Make a map of Array2's items (by id) and each of Array2's details (by id), and then you can iterate over Array1 and mutate its properties with low complexity:
const items2ById = {};
for (const item of Array2) {
items2ById[item.id] = item;
}
const items2DetailsById = {};
for (const detail of Array2.flatMap(({ details }) => details)) {
items2DetailsById[detail.id] = detail;
}
for (const item of Array1) {
if (!items2ById[item.id]) continue;
for (const detail of item.details) {
if (items2DetailsById[detail.id]) {
detail.rate = items2DetailsById[detail.id].rate;
}
}
}
Note that since you're mutating the existing objects, .map isn't really appropriate, since you don't really care to create a new array - instead, just iterate over the array and mutate it as needed.
let Array1 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "100"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "300"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "200"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "300"
}
]
},
{
id: 3,
name: "Tea",
details: [{
id: "16",
name: "Tea leaf",
quantity: "50",
rate: "700"
}]
}
]
let Array2 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "500"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "700"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "800"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "8000"
}
]
}
];
const items2ById = {};
for (const item of Array2) {
items2ById[item.id] = item;
}
const items2DetailsById = {};
for (const detail of Array2.flatMap(({ details }) => details)) {
items2DetailsById[detail.id] = detail;
}
for (const item of Array1) {
if (!items2ById[item.id]) continue;
for (const detail of item.details) {
if (items2DetailsById[detail.id]) {
detail.rate = items2DetailsById[detail.id].rate;
}
}
}
console.log(Array1);

display countries based on selection of id from a complex JSON structure using Javascript Map or Filter Method

I have a JSON structure which is bit complex and I want to display the corresponding items based on the selection of Id. For example, in my JSON structure I have the sections of continent and under each continent countries are listed within the property names "Levels".So, I want to filter each continent based on the id from the "Levels" property.
So, if the "Country.Level.Id === 6" it should display the Country.Name="America". I have been trying to make it work by using JavaScript Map and Filter method but couldn't make it work.
Here is my SandBox Link: https://codesandbox.io/s/dark-feather-ugvxv?file=/src/index.js:0-1294
The data:
const items = [
{
Country: [
{
Id: "1",
Name: "Europe",
Levels: [
{
Id: "1",
Name: "Finland",
DisplayName: "Finland"
}
]
},
{
Id: "1",
Name: "ASIA",
Levels: [
{
Id: "2",
Name: "Bangladesh",
DisplayName: "Bangladesh"
},
{
Id: "3",
Name: "India",
DisplayName: "India"
},
{
Id: "4",
Name: "Pakistan",
DisplayName: "Pakistan"
}
]
},
{
Id: "3",
Name: "America",
Levels: [
{
Id: "5",
Name: "USA",
DisplayName: "USA"
},
{
Id: "6",
Name: "Canada",
DisplayName: "Canada"
},
{
Id: "7",
Name: "Australia",
DisplayName: "Australia"
}
]
},
{
Id: "4",
Name: "Africa",
DisplayName: "Africa",
Levels: [
{
Id: "8",
Name: "Nigeria",
DisplayName: "Nigeria"
}
]
}
]
}
];
My coding attempt:
const selectById = "5";
const countries = items[0].Country;
const result = countries.filter(item => item.Levels.Id === selectById);
console.log(result);
According to your data structure, this function will find a continent from a country id:
function findContinentByCountryId(items, id) {
return items[0].Country.find((continent) => {
return continent.Levels.some(country => country.Id === id)
})
}
You can test it with the snippet below:
function findContinentByCountryId(items, id) {
return items[0].Country.find((continent) => {
return continent.Levels.some(country => country.Id === id)
})
}
<form>
<label for="country-id">Country id:</label>
<input id="country-id">
<input type="submit" value="Find continent by country id">
</form>
<span></span>
<script>
const items = [
{
Country: [
{
Id: "1",
Name: "Europe",
Levels: [
{
Id: "1",
Name: "Finland",
DisplayName: "Finland"
}
]
},
{
Id: "1",
Name: "ASIA",
Levels: [
{
Id: "2",
Name: "Bangladesh",
DisplayName: "Bangladesh"
},
{
Id: "3",
Name: "India",
DisplayName: "India"
},
{
Id: "4",
Name: "Pakistan",
DisplayName: "Pakistan"
}
]
},
{
Id: "3",
Name: "America",
Levels: [
{
Id: "5",
Name: "USA",
DisplayName: "USA"
},
{
Id: "6",
Name: "Canada",
DisplayName: "Canada"
},
{
Id: "7",
Name: "Australia",
DisplayName: "Australia"
}
]
},
{
Id: "4",
Name: "Africa",
DisplayName: "Africa",
Levels: [
{
Id: "8",
Name: "Nigeria",
DisplayName: "Nigeria"
}
]
}
]
}
];
const form = document.querySelector('form')
const input = document.querySelector('input')
const result = document.querySelector('span')
form.addEventListener('submit', (event) => {
event.preventDefault()
const continent = findContinentByCountryId(items, input.value)
result.textContent = continent ? continent.Name : 'Continent not found'
})
</script>
Side note
I don't know the context of your problem, but be aware that object properties are usually camelCased in javascript (instead of PascalCased in your case) and that Country and Levels might not be ideal names for the corresponding data. Furthermore, in case this wasn't intentional, Europe and Asia have the same id in your dataset.
You have to change your filter method appropriately it'll work
countries.filter(item => item.Levels.find(elem => elem.Id === selectById))
SandboxLink

Accessing an object property from outside scope

So I have 4 jsons with that looks like this:
{
"group": "A",
"id": "50"
"person": [
{
"name": 'Joe',
"age": '29'
},
{
"name": 'Jessie',
"age": '27'
}
]
}
I used this function to create an array with all the people from 4 different json's files.
list.forEach(list => {
list.person.forEach(person => {
peopleArray.push(person);
});
})
The problem is, when I pick a position from that array, I want to be able to access the group and the ID as well for example:
console.log(peopleArray[1].group);
Is that possible? Or I would have to those values inside the person?
Just include those values in the person object
const data = {
group: "A",
id: "50",
person: [
{
name: 'Joe',
age: '29'
},
{
name: 'Jessie',
age: '27'
}
]
}
data.person.map(obj => ({...obj, group: data.group, groupId: data.id}))
The result is:
[
{
age: "29",
group: "A",
groupId: "50",
name: "Joe"
},
{
age: "27",
group: "A",
groupId: "50",
name: "Jessie"
}
]

Add the key value based on property in array object javascript

I would like to know how to map the key value pair based on property in javascript.
I need to add the title property to obj1 if the name matches.
var obj1 = [
{"item": 1, code: "SG", name: "Engg", status: "A"},
{"item": 2, code: "TH", name: "Civil", status: "C"},
{"item": 1, code: "ML", name: "IT", status: "I"}
]
var obj2 = [
{"name": "Engg", "title": "Service"},
{"name": "Civil", "title": "MRT"}
]
Expected Output
var newobj= [
{"item": 1, code: "SG", name: "Engg", status: "A", title: "Service"},
{"item": 2, code: "TH", name: "Civil", status: "C",title:"MRT"},
{"item": 1, code: "ML", name: "IT", status: "I"}
]
var obj1 = [{
"item": 1,
code: "SG",
name: "Engg",
status: "A"
},
{
"item": 2,
code: "TH",
name: "Civil",
status: "C"
},
{
"item": 1,
code: "ML",
name: "IT",
status: "I"
}
]
var obj2 = [{
"name": "Engg",
"title": "Service"
},
{
"name": "Civil",
"title": "MRT"
}
]
const a = obj1.map(el => ({
...el,
...obj2.find(item => item.name === el.name)
}))
console.log(a)
1) Build titles object from obj2
2) Use reduce method on obj1 and update title from obj2.
var obj1 = [
{ item: 1, code: "SG", name: "Engg", status: "A" },
{ item: 2, code: "TH", name: "Civil", status: "C" },
{ item: 1, code: "ML", name: "IT", status: "I" }
];
var obj2 = [
{ name: "Engg", title: "Service" },
{ name: "Civil", title: "MRT" }
];
const titles = obj2.reduce((acc, { name, title }) => (acc[name] = title, acc), {});
const updated = obj1.map(item => ({
...item,
title: titles[item.name] || ""
}));
console.log(updated);

Categories

Resources