This is a bit of a tough problem to explain, so I'll do my best.
I have two arrays, Categories and Items, and I'm attempting to build a third array called CategoryItems based off of those first two arrays. The function I currently have to build it looks like this:
const newCategoryItems = data.map(( item, i ) => {
const category = categoriesData.find(c => c.name === item.category_name);
return {
item_id: bulkInsertData[i].id,
category_id: category?.id,
position: ???
};
});
console.log({ newCategoryItems });
Each Category can have multiple Items. What I would like to do is assign that specific Item's position within that Category. So for example, if Category 1 contains five Items, then their positions would increment from 1-5, and once Category 2 is detected then the next Items would start their position at 1, and so on.
Is this possible within my current function?
Edit Here is some sample data:
raw data
const data = [
{
name: 'Item 1',
price: 0,
quantity: 1,
url: null,
user_id: 1,
category_name: 'Category 1',
qty: null
},
... other raw data
]
I am then inserting those into my database and receiving these back with their assigned IDs. categories:
const categoriesData = [
{
id: 148,
name: 'Category 1',
list_id: 2,
updated_at: '2022-07-28T18:00:23.09351 00:00',
created_at: '2022-07-28T18:00:23.09351 00:00',
},
{
id: 149,
name: 'Category 2',
list_id: 2,
updated_at: '2022-07-28T18:00:23.09351 00:00',
created_at: '2022-07-28T18:00:23.09351 00:00',
},
... other categories
]
items:
const bulkInsertData = [
{
id: 677,
name: 'Item 1',
price: 0,
quantity: 1,
url: null,
user_id: 1
created_at: '2022-07-28T18:00:22.810136 00:00',
updated_at: '2022-07-28T18:00:22.810136 00:00',
},
{
id: 678,
name: 'Item 2',
price: 0,
quantity: 1,
url: null,
user_id: 1
created_at: '2022-07-28T18:00:22.810136 00:00',
updated_at: '2022-07-28T18:00:22.810136 00:00',
},
{
id: 679,
name: 'Item 3',
price: 0,
quantity: 1,
url: null,
user_id: 1
created_at: '2022-07-28T18:00:22.810136 00:00',
updated_at: '2022-07-28T18:00:22.810136 00:00',
},
...other items
]
CodePudding user response:
This would work. I've edited the test data by adding category directly to the first array to make this easier/more clear to reproduce. You could probably make an even more terse version using array.reduce()
.
const items = [
{
id: 677,
name: 'Item 1',
price: 0,
quantity: 1,
url: null,
user_id: 1,
created_at: '2022-07-28T18:00:22.810136 00:00',
updated_at: '2022-07-28T18:00:22.810136 00:00',
category: 'test1'
},
{
id: 678,
name: 'Item 2',
price: 0,
quantity: 1,
url: null,
user_id: 1,
created_at: '2022-07-28T18:00:22.810136 00:00',
updated_at: '2022-07-28T18:00:22.810136 00:00',
category: 'test2'
},
{
id: 679,
name: 'Item 3',
price: 0,
quantity: 1,
url: null,
user_id: 1,
created_at: '2022-07-28T18:00:22.810136 00:00',
updated_at: '2022-07-28T18:00:22.810136 00:00',
category: 'test1'
}
];
const categoryCounter = {};
const newCategoryItems = items.map(( item ) => {
if ( categoryCounter.hasOwnProperty( item.category ) ) {
categoryCounter[item.category] ;
} else {
categoryCounter[item.category] = 1;
}
return {
item_id: item.id,
category_id: item.category,
position: categoryCounter[item.category]
};
});
console.log( newCategoryItems );
https://stackoverflow.com/questions/73170086/increment-position-property-by-1-for-each-matching-property#
CodePudding user response:
Using object to store positions:
const categories = {}
function position(item, category) {
if (!(category in categories)) categories[category] = {}
if (!(item in categories[category])) categories[category][item] = categories[category][item] = Object.keys(categories[category]).length 1
return categories[category][item]
}
position("item 1", "category 1")
1
position("item 1", "category 1")
1
position("item 2", "category 1")
2
position("item 3", "category 2")
1
position("item 4", "category 1")
3
categories
{category 1: {…}, category 2: {…}}
category 1: {item 1: 1, item 2: 2, item 4: 3}
category 2: {item 3: 1}
Using array to store positions:
const categories = {}
function position(item, category) {
if (!(category in categories)) categories[category] = []
if (!(item in categories[category])) categories[category].push(item)
return categories[category].indexOf(item)
}
position("item 1", "category 1")
0
position("item 2", "category 1")
1
position("item 3", "category 2")
0
position("item 4", "category 1")
2
categories
{category 1: Array(3), category 2: Array(1)}
category 1: (3) ['item 1', 'item 2', 'item 4']
category 2: ['item 3']
[[Prototype]]: Object