How to delete an item from my Reducer Object? - javascript

I have an object in my reducer like this :
clientData : {
1080 : [{ID : 1111,name : 'John'},{ID : 2222,name : 'Stan'},],
1090 : [{ID : 3333,name : 'Adam'},{ID : 4444,name : 'Alan'},]
}
And I want to be able to delete an item (for example Stan with 2222 ID's)
The problem that is I don't have the key of my property (1080), and I don't have any idea how to achieve it.
I've tried the Object.values(object1) but it convert my object to array and I lost all my architecture.
Have you an idea please ?

Removing from existing objects might not be good, you can use Object.entries and filter to remove id.
If you want to change existing pass data to reducer
const data = {
1080: [
{ ID: 1111, name: "John" },
{ ID: 2222, name: "Stan" },
],
1090: [
{ ID: 3333, name: "Adam" },
{ ID: 4444, name: "Alan" },
],
};
const remove = (id, data) => {
const entries = Object.entries(data);
return entries.reduce((acc, [key, value]) => {
const newValue = value.filter((item) => item.ID !== id);
acc[key] = newValue;
return acc;
// return { ...acc, [key]: newValue };
}, {}); // for updating existing data here
};
console.log(remove(2222, data))

Related

How to update the value into a nested array of objects if value for specific key is same?

let data = [
{"name":"Dhanush","createdAt":"2021/01/13 16:57:53","songs":[]},
{"name":"Dharma","createdAt":"2021/01/13 17:02:47","songs":[]},
{"name":"Sachin","createdAt":"2021/01/13 17:30:45","songs":[]}
]
let name = "Dhanush"
let song = {
'id':1,
'duration': '5 mins',
'name': 'Bingo'
}
Here I need to loop the data array and check if data.name === name , if it s true I need to push the song object to the songs array inside the data.
this means
data = data.map(val => val.name === name ? val.songs = [...val.songs,song] : val.songs)
I tried like this. but it doesn't work.
Your help is much appreciated.
Thanks
You are not returning val when using map method.
let data = [
{ name: 'Dhanush', createdAt: '2021/01/13 16:57:53', songs: [] },
{ name: 'Dharma', createdAt: '2021/01/13 17:02:47', songs: [] },
{ name: 'Sachin', createdAt: '2021/01/13 17:30:45', songs: [] },
];
const name = 'Dhanush';
const song = {
id: 1,
duration: '5 mins',
name: 'Bingo',
};
data = data.map(
(val) => (
val.name === name ? (val.songs = [...val.songs, song]) : val.songs, val
)
);
console.log(data);

Compare different collections and and take a value

I want to find a nice / elegant (maybe using lodash) way to do compare 2 different colections and on equality (according to my defenition of equal) take some value from 1 collection and another value from the other collection and map it to a new collection, like so:
const filter1 = [{
columnName : "date",
value : "12/5"
},
{
columnName : "age",
value : "12"
}]
const filter2 = [{
valueName : "age",
displayName: "Age"
},
{
valueName : "date",
displayName: "DateD"
}]
filter1.map((val) => ({
displayName: filter2.find(filter => filter.valueName === val.columnName).displayName,
value : val.value
}))
to get:
[{
displayName: "DateD",
value: "12/5"
}, {
displayName: "Age",
value: "pa"
}]
Convert the 2nd array to a Map using valueName as the rest of the object as the value. Create the new array by mapping the 1st array, getting the items from the Map using columnName and merging it with the values from the 1st array using object spread.
const fn = (arr1, arr2) => {
const arr2Map = new Map(arr2.map(({ valueName, ...rest }) => [valueName, rest]))
return arr1.map(({ columnName, ...rest }) => ({
...arr2Map.get(columnName),
...rest
}))
}
const filter1 = [{"columnName":"date","value":"12/5"},{"columnName":"age","value":"12"}]
const filter2 = [{"valueName":"age","displayName":"Age"},{"valueName":"date","displayName":"DateD"}]
const result = fn(filter1, filter2)
console.log(result)

Update only a single key in a javascript object with map

I want to update my thumbnail key in my object.
products :[
{
id: 1,
name: "sth,
thumb : 'abc.jpg'
}
];
I want to update the products.thumb of all the objects in that array like thumb: 'server/abc.jpg
searchedProducts = products.map(product => {
return Object.assign({},
product,
product.thumb = product.thumb ? 'server'+product.thumb : '')
});
Current output
[{
0: 's,
1: 'e',
3: 'r',
4: 'v',
5: 'e',
id: 1,
thumb :'server/abc.jpg'
}]
With spread syntax:
const products = [
{
id: 1,
name: 'sth',
thumb : 'abc.jpg'
}
];
searchedProducts = products.map(product => {
const thumb = product.thumb ? 'server/' + product.thumb : '';
return { ...product, thumb };
});
console.log(searchedProducts);
You probably meant to use Object.assign like so:
const products = [
{
id: 1,
name: 'sth',
thumb : 'abc.jpg'
}
]
const searchedProducts = products.map(product => {
return Object.assign({}, product, {
thumb: product.thumb ? 'server/' + product.thumb : ''
})
})
console.log(searchedProducts)
In the above snippet I'm merging:
An empty object.
With the currently iterated product object.
With another object containing the computed thumb key.
Why would this not work for you?
const products = [
{
id: 1,
name: 'sth',
thumb : 'abc.jpg'
},
{
id: 2,
name: 'sth',
thumb : 'def.jpg'
}
];
// Non mutating
let copy = JSON.parse(JSON.stringify(products));
copy.forEach(product => {
product.thumb = product.thumb ? 'copyserver/'+product.thumb : '';
});
console.log(copy);
// Mutating
products.forEach(product => {
product.thumb = product.thumb ? 'server/'+product.thumb : '';
});
console.log(products);
You could destructure and get the thumb property and keep the remaining properties in rest. This way you can keep the remaining properties as they are:
const products = [{
id: 1,
name: "sth",
thumb: 'abc.jpg'
},
{
id: 2,
name: "sth2",
thumb: 'def.jpg'
}
];
const newProducts = products
.map(({thumb, ...rest}) => ({ thumb: thumb ? `server/${thumb}` : ``, ...rest }));
console.log(newProducts)
You could also do this using reduce, initialising your start with an empty array,
const result = products.reduce((prev, next) => {
next.thumb = `server/${next.thumb}`;
prev.push(next);
return prev;
}, []);
console.log(result);
Just another way of doing it other than map.
You can use destructing assignment with .map to modify all thumb properties.
See working example below:
const products = [{id:1,name:"sth",thumb:"abc.jpg"},{id:2,name:"byt",thumb:"def.jpg"},{id:3,name:"mth"}],
res = products.map(({thumb, ...others}) => ({...others, "thumb": thumb ? "server/" + thumb:''}));
console.log(res);

Javascript can't group objects with 2 values

I have this object data:
[ RowDataPacket {
id: 59,
steamid: '76561198220437096',
product_id: 23,
status: 1,
date: 2017-12-18T17:27:19.000Z,
message: null,
name: 'CS.MONEY',
amount: 100,
website: 'csgo500' },
RowDataPacket {
id: 60,
steamid: '76561198220437096',
product_id: 24,
status: 1,
date: 2017-12-18T17:27:19.000Z,
message: null,
name: 'CS.MONEY',
amount: 250,
website: 'csgo500' },
RowDataPacket {
id: 61,
steamid: '76561198220437096',
product_id: 23,
status: 1,
date: 2017-12-18T17:27:19.000Z,
message: null,
name: 'CS.MONEY',
amount: 100,
website: 'csgo500' },
RowDataPacket {
id: 62,
steamid: '76561198345348530',
product_id: 6,
status: 1,
date: 2017-12-18T20:05:55.000Z,
message: null,
name: 'wal gruche',
amount: 100,
website: 'csgoatse' }
Im trying to sort this data with steamid and website, i managed to sort this only by one value like this:
var groupedOrders = {};
row.forEach(function(item){
var list = groupedOrders[item.steamid];
if(list){
list.push(item);
} else{
groupedOrders[item.steamid] = [item];
}
});
My idea was to make two dimensional array but for some reason i cant do it like this:
var list = groupedOrders[item.steamid][item.website];
It throws me an error "Cant read property ... of undefined"
Now my code looks like this:
var groupedOrders = {};
row.forEach(function(item){
var list = groupedOrders[item.steamid][item.website];
if(list){
list.push(item);
} else{
groupedOrders[item.steamid][item.website] = [item];
}
});
Do you have any ideas how to fix this errors?
The problem is that var list = groupedOrders[item.steamid][item.website] is actually saying:
var temp = groupedOrders[item.steamid];
var list = temp[item.website];
There is no entry at groupedOrders[item.steamid] and so line one sets temp to undefined. The second line tries to index into undefined which is an error.
You would have to split the code out and essentially do the whole one-key grouping twice:
var outerList = groupedOrders[item.steamid];
if (!outerList)
outerList = groupedOrders[item.steamid] = {};
var innerList = outerList[item.website];
if (innerList)
innerList.push(item);
else
outerList[item.website] = [item];
(I have not tested this code but it is the right shape.)
The following works by creating a recursive groupBy grouping function for each of the fields supplied as an argument.
These dynamically created groupBy functions are then invoked one by one, passing the result between, starting with the supplied data.
Each groupBy function instance creates an object and adds properties to it corresponding to the key values for the field being grouped.
By calling these groupBy functions successively, we create a progressively more nested tree of objects, with groups at each successive level marked as being groups using a symbol.
The final result is a nest (a tree!) of objects, with keys corresponding to the field used for indexing at that level.
Finally, we flatten the nest and the final order is visible.
const flatten = o => Object.values(o).reduce((acc, c) => (Array.isArray(c) ? [...acc, ...c] : typeof c === 'object' ? [...acc, ...flatten(c)] : [...acc, c]), []);
const flow = (...fns) => data => fns.reduce((acc, c) => c(acc), data);
const GROUP = Symbol('group');
const asGroup = (result = []) => ((result[GROUP] = true), result);
const isGroup = o => o[GROUP];
const groupBy = field => (data, key) =>
data.reduce((acc, c) =>
((key = c[field]), (acc[key] ?
(acc[key].push(c), acc) :
((acc[key] = asGroup([c])), acc))), {});
const recurse = (test) => (transform) => o =>
test(o)
? transform(o)
: Object.entries(o).reduce(
(acc, [k, v]) => (test(v) ?
((acc[k] = transform(v)), acc) :
((acc[k] = recurse(test)(transform)(v)), acc)), {});
const group = (...fields) => flow(...fields.map(flow(groupBy, recurse(isGroup))), flatten);
const rows = asGroup([
{
id: 0,
steamid: '2',
website: 'a'
},
{
id: 1,
steamid: '2',
website: 'b'
},
{
id: 2,
steamid: '2',
website: 'a'
},
{
id: 3,
steamid: '1',
website: 'b'
},
{
id: 4,
steamid: '0',
website: 'b'
}
]);
console.log(JSON.stringify(group('steamid', 'website')(rows), null, 2));

Count elements that have the same value for a specific property and put the result in an array of objects

Using Array.reduce, I am trying to count the elements that have the same value for a specific property. I want to put the result in an array of objects containing a property for the value of the grouped by property and another one for the count. How can I do this easily in javascript ?
const CATEGORY = {
STRATEGY: 'STRATEGY',
CONTENT: 'CONTENT',
ADVERTISING: 'ADVERTISING',
MEASURMENT: 'MEASURMENT'
}
const lessons = [
{
title: 'ohoho',
category: CATEGORY.STRATEGY
}, {
title: 'hihihi',
category: CATEGORY.CONTENT
}, {
title: 'hello',
category: CATEGORY.CONTENT
}
]
let categoryLessonCount = lessons.reduce(function (acc, lesson) {
acc[lesson.category] ? acc[lesson.category]++ : acc[lesson.category] = 1
return acc
}, {})
console.log(categoryLessonCount[CATEGORY.STRATEGY])
console.log(categoryLessonCount[CATEGORY.CONTENT])
Actual categoryLessonCount value :
Object
{
STRATEGY: 1,
CONTENT: 2
}
Wanted categoryLessonCount value :
Array
[
{
title: 'STRATEGY',
count: 1
}, {
title: 'CONTENT',
count: 2
}
]
You already got the what you want just transform it into an array
const CATEGORY = {
STRATEGY: 'STRATEGY',
CONTENT: 'CONTENT',
ADVERTISING: 'ADVERTISING',
MEASURMENT: 'MEASURMENT'
}
const lessons = [{
title: 'ohoho',
category: CATEGORY.STRATEGY
}, {
title: 'hihihi',
category: CATEGORY.CONTENT
}, {
title: 'hello',
category: CATEGORY.CONTENT
}]
let count = lessons.reduce(function(acc, lesson) {
acc[lesson.category] ? acc[lesson.category] ++ : acc[lesson.category] = 1
return acc
}, {})
// transform count into what you want
let categoryLessonCount = [];
for (let cat in count) {
categoryLessonCount.push({
'title': cat,
'count': count[cat]
});
}
console.log(categoryLessonCount)
Something like this should work:
let categoryLessonCount = lessons.reduce(function(acc, lesson) {
let found = false
for (const item of acc) {
if (item.title === lesson.category) {
item.count++
found = true
}
}
if (!found) {
acc.push({
title: lesson.category,
count: 1
})
}
return acc
}, [])
Your main issue is that your accumulating an object but expecting an array (note the final argument to reduce).
Short solution using Object.keys and Array.prototype.map functions:
...
let categoryLessonCount = lessons.reduce(function (acc, lesson) {
acc[lesson.category] ? acc[lesson.category]++ : acc[lesson.category] = 1
return acc
}, {})
let counts = Object.keys(categoryLessonCount).map(
(k) => ({title: k, count: categoryLessonCount[k]})
)
console.log(counts);

Categories

Resources