Related
Hi i need some help to update the userSettings variable, for example if i remove a product of the products array, i need to update the sortedProducts array of the userSettings.categories array, i'm trying with nested for loops but i would like to improve performance with functional array methods. This is what i've been trying, thanks in advance community.
let products = [
{id: 1, name: 'Brasilian', category: 'cofee'},
{id: 2, name: 'Colombian', category: 'cofee'},
{id: 3, name: 'Apple', category: 'fruit'},
{id: 4, name: 'Strawberry', category: 'fruit'},
{id: 5, name: 'Banana', category: 'fruit'},
{id: 6, name: 'Pepper', category: 'spices'},
{id: 7, name: 'Salt', category: 'spices'}
]
let userSettings = {
categories: [
{name: 'fruit', sortedProducts: [5, 3, 4]},
{name: 'spices', sortedProducts: []},
{name: 'cofee', sortedProducts: []},
]
}
// lets remove the strawberry product
products.splice(3, 1);
console.log(products);
// i need to update userSettings
const updateUserSettings = (() => {
for(let i = 0; i < userSettings.categories.length; i++){
if(userSettings.categories[i].sortedProducts.length){
console.log(userSettings.categories[i].sortedProducts);
for(let j = 0; j < products.length; j++){
if(products[j].category == userSettings.categories[i] && !userSettings.categories[i].sortedProducts.includes(products[j].id)){
console.log('no includes')
}
}
}
}
})();
expectedOutput = {
categories: [
{name: 'fruit', sortedProducts: [5, 3]},
{name: 'spices', sortedProducts: []},
{name: 'cofee', sortedProducts: []},
]
}
Since the other categories need to have empty arrays, the best way would be to remove any existing sortedProducts in userSettings that no longer exist in products.
userSettings.categories.forEach(category => {
// get the product ids for the category
let filteredProductIds = products.filter(product => product.category === category.name)
.map(product => product.id)
// remove any id that no longer exists in products from sortedProducts
category.sortedProducts = category.sortedProducts.filter(sortedProduct => filteredProductIds.includes(sortedProduct))
})
I have an array of projects called rawProjects which looks like this:
rawProjects = [
{
id: 1,
name: "proj1",
technology: [
0: {id: 21, project_id: 1,name: "java"},
1: {id: 22, project_id: 1,name: "c++"}
]
},
{
id: 2,
name: "proj2",
technology: [
0: {id: 23, project_id: 2,name: "sql"},
1: {id: 24, project_id: 2,name: "python"},
2: {id: 25, project_id: 2,name: "react"}
]
}
]
I also have an array of technology called tempTags which contains the technologies that the user enters to search from. So far I have been able to do the OR case where in I return the projects which contain either of the technologies mentioned by the user using:
const filteredProjects = rawProjects.filter(x => x.technology.some(g => tempArr.includes(g.name)))
So for example if tempTags = [sql, c++] both projects will be returned.
How do I implement the AND case such that only projects that contain both of these technologies are returned. Eg if tempTags = [java, c++] , only the first project will be returned. If tempTags = [sql, c++], nothing will be returned?
Iterate over the tempTags and check that .every one of them is included:
const rawProjects = [
{
id: 1,
name: "proj1",
technology: [
{id: 21, project_id: 1,name: "java"},
{id: 22, project_id: 1,name: "c++"}
]
},
{
id: 2,
name: "proj2",
technology: [
{id: 23, project_id: 2,name: "sql"},
{id: 24, project_id: 2,name: "python"},
{id: 25, project_id: 2,name: "react"}
]
}
]
const tempTags = ['java', 'c++'];
const filtered = rawProjects.filter(
p => {
const techNames = p.technology.map(({ name }) => name);
return tempTags.every(
tag => techNames.includes(tag)
);
}
);
console.log(filtered);
You'll also need to fix your syntax: arrays do not have key-value pairs, only values. (Remove the 0:, 1:, etc), and make sure to put commas in between array values (there should be a comma after "python"})
I have a question, how can I map and reduce an array like this:
[
{
id: 1,
Price: 50,
Item: {id: 1, Name: "A"},
Date: {id: 1, Start: "202001"}
},
{
id: 2,
Price: 100,
Item: {id: 1, Name: "A"},
Date: {id: 2, Start: "202002"}
},
{
id: 3,
Price: 200,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001"}
}
]
I'm writing an app in React and I want to show those values grouped in a table.
It should look something like this:
ITEM
202001
202002
A
50
100
B
-
200
I would like to be able to do this with the array:
[
{
id: 1,
Item: {id: 1, Name: "A"},
Date: [{id: 1, Start: "202001",Price: "50"},{id: 2, Start: "202002",Price: "100"}]
},
{
id: 2,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001",Price: "200"}
}
]
Any suggestions to get to what I need?
You can use Array.prototype.reduce() and then use Object.values like so:
const arr = [
{
id: 1,
Price: 50,
Item: {id: 1, Name: "A"},
Date: {id: 1, Start: "202001"}
},
{
id: 2,
Price: 100,
Item: {id: 1, Name: "A"},
Date: {id: 2, Start: "202002"}
},
{
id: 3,
Price: 200,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001"}
}
]
const res = Object.values(arr.reduce((acc, {Item, Date, Price}) => {
if(!acc[Item.id]) {
acc[Item.id] = {
id: Item.id,
Item,
Date: [{...Date, Price}]
};
} else {
acc[Item.id].Date = [...acc[Item.id].Date, {...Date, Price}];
}
return acc;
}, {}));
console.log(res);
You can use groupBy method of lodash to group your dataset according to Item.Name.
First get the package:
npm i lodash.groupby
Then use it in your code as
import groupBy from 'lodash.groupby'
const tempData = [
{
id: 1,
Price: 50,
Item: {id: 1, Name: "A"},
Date: {id: 1, Start: "202001"}
},
{
id: 2,
Price: 100,
Item: {id: 1, Name: "A"},
Date: {id: 2, Start: "202002"}
},
{
id: 3,
Price: 200,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001"}
}
]
groupBy(tempData, 'Item.Name')
/*
Will result as below
{
A: [
//objects with 'Item.Name' === 'A'
],
B: [
//objects with 'Item.Name' === 'B'
]
}
*/
Then, you need to populate your table with the keys inside the response from groupBy
I'll just ask on how to remove some elements in an object array using lodash.
var fruits = [
{ id: 1, name: 'Apple', price: 55, qty: 3, status: 'ripe' },
{ id: 2, name: 'Banana', price: 55, qty: 4, status: 'ripe' },
{ id: 3, name: 'Pineaple', price: 55, qty: 2, status: 'ripe' }
];
How will I remove the qty and status in all object array so it will look like this
[
{ id: 1, name: 'Apple', price: 55 },
{ id: 2, name: 'Banana', price: 55 },
{ id: 3, name: 'Pineaple', price: 55 }
]
Without any library, you can use map and destructure the object.
var fruits = [{"id":1,"name":"Apple","price":55,"qty":3,"status":"ripe"},{"id":2,"name":"Banana","price":55,"qty":4,"status":"ripe"},{"id":3,"name":"Pineaple","price":55,"qty":2,"status":"ripe"}]
var result = fruits.map(({qty,status,...r}) => r);
console.log(result);
You can do it without using a library too.
Use Array.map
var fruits = [{ id: 1, name: 'Apple', price: 55, qty: 3, status: 'ripe' },{ id: 2, name: 'Banana', price: 55, qty: 4, status: 'ripe' },{ id: 3, name: 'Pineaple', price: 55, qty: 2, status: 'ripe' }];
let result = fruits.map(({status,qty,...rest}) => rest);
console.log(result);
You can just iterate through the object using forEach and delete
the unwanted fields with the plain old delete operator.
This method cleans your current object, Without the need for a new object to be defined.
fruits.forEach((val) => {delete val.qty; delete val.status})
It is true that you don't need to use a library to effectively delete properties of an object though if you want to use lodash here is an example of how you would do that by using the .pick method:
let pickedFruits = [];
for (let i in fruits) {
pickedFruits.push(_.pick(fruits[i], ["id", "name", "price"]));
}
where pickedFruits will be the new array of objects each having an id, name and a price property.
I have two arrays that contain objects. Objects on the first array contain an id, name and age.
I have tried many answers that I have found on StackOverflow such as this one and this one and elsewhere online, however it is proving quite tricky and I am unable to get this working.
var arrOne = [
{id: 1, name: 'Raul', age: 18},
{id: 2, name: 'Sarah', age: 20},
{id: 3, name: 'Sanchez', age: 30}
];
The second array contains an id that is related to the users in the first array and and an associated image.
var arrOne = [
{id: 1, image: 'raulrod.jpg'},
{id: 2, image: 'saz.jpg'},
{id: 1, image: 'hola.jpg'},
{id: 3, image: 'qtal.jpg'},
{id: 1, image: 'senor.jpg'},
{id: 3, image: 'ciao.jpg'},
];
After they are combined I am looking for a result like this with each object combining the objects in both arrays based on the id.
var finalArr = [
{id: 1, name: 'Raul', age: 18 image: 'raulrod.jpg'},
{id: 1, name: 'Raul', age: 18 image: 'hola.jpg'},
{id: 1, name: 'Raul', age: 18 image: 'senor.jpg'},
{id: 2, name: 'Raul', age: 20 image: 'saz.jpg'}
{id: 3, name: 'Raul', age: 30 image: 'ciao.jpg'},
{id: 3, name: 'Raul', age: 30 image: 'qtal.jpg'},
];
With plain ES6, you could map the a new object with the properties of arrOne and, with Array#find, the properties of the related object of arrTwo.
If needed, you could later sort the result by id.
var arrOne = [{ id: 1, name: 'Raul', age: 18 }, { id: 2, name: 'Sarah', age: 20 }, { id: 3, name: 'Sanchez', age: 30 }],
arrTwo = [{ id: 1, image: 'raulrod.jpg' }, { id: 2, image: 'saz.jpg' }, { id: 1, image: 'hola.jpg' }, { id: 3, image: 'qtal.jpg' }, { id: 1, image: 'senor.jpg' }, { id: 3, image: 'ciao.jpg' }],
result = arrTwo.map(a => Object.assign({}, a, arrOne.find(b => a.id === b.id)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use array.map and array.find proptotypes:
var arrOne = [
{id: 1, name: 'Raul', age: 18},
{id: 2, name: 'Sarah', age: 20},
{id: 3, name: 'Sanchez', age: 30}
];
var arrTwo = [
{id: 1, image: 'raulrod.jpg'},
{id: 2, image: 'saz.jpg'},
{id: 1, image: 'hola.jpg'},
{id: 3, image: 'qtal.jpg'},
{id: 1, image: 'senor.jpg'},
{id: 3, image: 'ciao.jpg'}
];
var finalArr = arrTwo.map(item => {
var correspondingObj = arrOne.find(obj => obj.id === item.id)
item.name = correspondingObj.name;
item.age = correspondingObj.age;
return item;
});
console.log(finalArr);
Actually, https://stackoverflow.com/a/19480257/5809250 should help you.
Have you included underscore - http://underscorejs.org/#extend?
If you do not want to include underscore, you may use [assign][3] function.
Also, I wrote the example. It is not so perfect so you may try to improve it by yourself.