Typescript map collection - javascript

I have this complex models which i am trying to map.
I have an array of Carts containing id, name and etc
I have a dictionary where key is a type and its value is the different products.
I have added an example of what the result should looks like at the bottom of page.
My attempt but got stuck on how to filter
carts.forEach(cart => {
const productList = cart.products; //list of products
Object.entries(content.data).forEach(([key, values]) => {
const sizeList = values.map(x => x.sizeList); //list of size
// i am stuck here
});
});

const getCartsWithProductNames = (carts = [], content = {}) => {
// create a Map with productId-sizeId as key, and size name as value
const productSizeNameMap =
Object.values(content)
.flat()
.reduce((map, { productId, sizeList = [] }) => {
sizeList.forEach(({ sizeId, name }) =>
map.set(`${productId}-${sizeId}`, name)
);
return map;
}, new Map);
// return carts list with product items having names from productSizeNameMap
return carts.map(({ cartId, cartName, products = [] }) => ({
id: cartId,
name: cartName,
productItems: products.map(({ id, size, quantity, isVisible }) => ({
id, quantity, isVisible, name: productSizeNameMap.get(`${id}-${size}`)
}))
}));
}
const
carts = [
{
cartId: 500,
cartName: "Some name",
products: [ { id: 1, size: 10, quantity: 1, isVisible: true }, { id: 2, size: 13, quantity: 10, isVisible: true } ]
}
],
content = {
"Drinks": [
{ productId: 1, sizeList: [ { sizeId: 10, name: "100ml beer" }, { sizeId: 9, name: "200ml beer" } ]
}
],
"Food": [
{
productId: 2,
sizeList: [ { sizeId: 12, name: "6 wings" }, { sizeId: 13, name: "12 wings" } ]
}
]
};
console.log( getCartsWithProductNames(carts, content) );

Related

Being able to remove duplicate keys from an array of objects

I have a question about how I can delete the existing elements, for example, in my case "Tallas" is repeated, could you please help me? Thank you very much to those who are willing to help me to solve this problem
const data =
[ { atributos: { Tallas: [{ id: 0, name: 'XS' }, { id: 1, name: 'S' }] }}
, { atributos: { Calzado: [{ id: 0, name: '10' }, { id: 1, name: '9.5' }] }}
, { atributos: { Tallas: [{ id: 0, name: 'XS' }] }}
]
The idea is to have this json format with the last "Tallas" since it is the last one that I added through my dynamic form.
const expected =
[{ atributos: { Calzado: [{ id: 0, name: '10' }, { id: 1, name: '9.5' }] }}
, { atributos: { Tallas: [{ id: 0, name: 'XS' }] }}
]
How do I do this is there a way to do it, I've tried with filter plus the findindex but I can't get to eliminate the repetition of the json res= new.filter((arr, index, self) => index === self.findIndex( (t) => (t.attributes === arr.attributes )))
To unique the array of objects, we can use the Javascript Set module, if the array has complex nested objects, we can stringify each object before creating new Set data. this below function will unique the array of complex objects.
function unique_array(array = []) {
const newSetData = new Set(array.map((e) => JSON.stringify(e)));
return Array.from(newSetData).map((e) => JSON.parse(e));
}
this is a function that takes an array and return the same array but delete every duplicated item
function removeDuplicates(arr) {
return arr.filter((item,
index) => arr.indexOf(item) === index);
}
I didn't understant the part written in spanish so I hope this is what you are looking for
This is a solution specific to your question. this is not a generic solution.
const data = [
{
atributos: {
Tallas: [
{ id: 0, name: "XS" },
{ id: 1, name: "S" },
],
},
},
{
atributos: {
Calzado: [
{ id: 0, name: "10" },
{ id: 1, name: "9.5" },
],
},
},
{
atributos: {
Tallas: [
{ id: 0, name: "XS" },
{ id: 1, name: "S" },
],
},
},
];
function uniqueArray(array) {
const resultObject = array.reduce((acc, eachValue) => {
let keys = Object.keys(eachValue.atributos);
keys.forEach((eachKey) => {
if (!acc[eachKey]) {
acc[eachKey] = [];
}
let list = eachValue["atributos"][eachKey].map(
(each) => each.id + "-" + each.name
);
acc[eachKey].push(...list);
});
return acc;
}, {});
const resultArray = Object.keys(resultObject).reduce((acc, each) => {
let setData = Array.from(new Set(resultObject[each]));
acc.push({
atributos: {
[each]: setData.map((e) => {
return { id: e.split("-")[0], name: e.split("-")[1] };
}),
},
});
return acc;
}, []);
return resultArray;
}
const result = uniqueArray(data)
console.log("result ", JSON.stringify(result, null, 2));

Javascript match two arrays by id

The goal is to match two arrays by id. I need to check if stopId is in both info and times arrays and combine matching arrays.
What should be the proper check to find out if id matches? I've attached an example, I was trying to implement using includes.
Could you please give me an advise?
const info = [
{
stopId: 1,
name: "N1"
},
{
stopId: 2,
name: "N2"
},
{
stopId: 3,
name: "N3"
}
]
const times = [
{
stopId: 1,
time: "T1"
},
{
stopId: 3,
time: "T2"
}
]
// Expected
// [
// {
// stopId: 1,
// name: "123",
// time: "T1"
// },
// {
// stopId: 2,
// name: "123"
// },
// {
// stopId: 3,
// name: "123",
// time: "T2"
// }
// ]
const res = () => {
const final = [];
info.forEach((item) => {
if (times.includes(item.stopId)) { // How to check if stopId matches
final.push({ })
}
})
}
console.log(res())
Try this one:
const result = info.map((item) => {
const time = times.find((time) => time.stopId === item.stopId)
return {
...item,
time: time ? time.time : null
}
})
Attached a working example
const info = [{
stopId: 1,
name: "N1"
},
{
stopId: 2,
name: "N2"
},
{
stopId: 3,
name: "N3"
}
]
const times = [{
stopId: 1,
time: "T1"
},
{
stopId: 3,
time: "T2"
}
]
// Expected
// [
// {
// stopId: 1,
// name: "123",
// time: "T1"
// },
// {
// stopId: 2,
// name: "123"
// },
// {
// stopId: 3,
// name: "123",
// time: "T2"
// }
// ]
const res = () => {
const final = [];
info.forEach((item) => {
let temp = { ...item
};
times.forEach((el) => {
if (item.stopId === el.stopId) {
temp = { ...temp,
...el
};
}
})
final.push(temp);
})
console.log(final);
}
res()
With includes you are comparing the objects of time to the stopId of the item. You have to select the stopId of the time first. You can use the operator find for example:
info.forEach((item) => {
if (times.find(t => t.stopId === item.stopId)) {
final.push({ })
}
})
You should try this code
var record1 = [
{
id: 66,
name: 'haris'
},
{
id: 873,
name: 'laxman'
},
]
var record2 = [
{
id: 99,
name: 'arjit'
},
{
id: 873,
name: 'laxman'
},
]
var result = record1.filter((elem, index) => elem.id == record2[index].id );

How to loop through two arrays of objects and get a new array with some data modified?

How to loop through two arrays of objects and get a new array with some data modified?
Arrays:
const products = [
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Tees',
},
];
const categories = [
{
name: 'Jeans',
},
{
name: 'Tees',
},
];
Need new categories array like this with new prop productCount:
const newCategories = [
{
name: 'Jeans',
productCount: 2,
},
{
name: 'Tees',
productCount: 0,
},
];
I tried this way but it doesn't work:
const newArr = categories.map((category) => {
let count = 0;
const index = products.findIndex((product) => category.name === product.category);
if (index > -1) {
return {
...category,
productCount: count++,
};
}
return {
...category,
productCount: 0,
};
});
Increasing the count number will not in that case because it will always start with zero. Instead, you can use the filter() method to find the number of products with a specific category and assign this number to productCount attribute.
const products = [{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Tees',
},
];
const categories = [{
name: 'Jeans',
},
{
name: 'Tees',
},
];
const newArr = categories.map((category) => {
const numberOfItems = products.filter((product) => category.name === product.category);
return {
...category,
productCount: numberOfItems.length,
};
});
console.log(newArr)
You can create an object and the transform it to array, something like this:
const products = [
{
brand: "Levis",
category: "Jeans"
},
{
brand: "Levis",
category: "Jeans"
},
{
brand: "Levis",
category: "Tees"
}
];
const categoriesObj = {};
products.forEach(({ brand, category }) => {
categoriesObj[category] ??= {
name: category,
productCount: 0
};
++categoriesObj[category].productCount;
});
const newCategories = Object.values(categoriesObj);
console.log(newCategories);
You can use the Array#Map method and add a productCount property using the Array#filter method
const products = [{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Tees',
},
];
const categories = [{
name: 'Jeans',
},
{
name: 'Tees',
},
];
const newCategories = [...categories].map(category => ({
...category,
productCount: products.filter(product => product.category === category.name).length
}))
console.log(newCategories)
You could do this with Array.reduce(), incrementing the productCount for each item. This should also be efficient, requiring only one iteration of the products array.
We'd run the reduce over both arrays, ensuring that we'll end up with a productCount of zero where no products for that category exist.
const products = [ { brand: 'Levis', category: 'Jeans', }, { brand: 'Levis', category: 'Jeans', }, { brand: 'Levis', category: 'Tees', }, ];
const categories = [ { name: 'Jeans', }, { name: 'Tees', }, { name: 'Foo', } ];
const result = Object.values([...categories, ...products].reduce((acc, { brand, category, name }) => {
const key = name || category;
acc[key] = acc[key] || { name: key, productCount: 0 };
if (category) acc[key].productCount++;
return acc;
}, {}));
console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; }

Intersection of two arrays in javascript

I want to search in a big array for different id from another array and print all intersections of those two arrays
I want to map through my bigTable and I want to create another array of correspondence, each found element must contain all fields+tableName+tableID like this :
const output = [{
ID: 1234,
title: 'title1',
TableName: 'loramIpsum',
TableId: 11,
},
{
ID: 98523,
title: 'mylasttitle',
TableName: 'table2',
TableId: 87545,
},
{
ID: 97766,
title: 'mylastdata',
TableName: 'table2',
TableId: 87545,
},
]
I've create a function but I think there is another best and sample solution, this is my function :
const getResult = (wantedData, bigArray) => {
return wantedData.flatMap((id) =>
bigArray.flatMap((family) =>
family.Tables.flatMap((table) => {
let item = table.myDatas.find((el) => el.ID === id);
if (item) {
item.Table = table.TableName;
item.familyId = family.GridId;
return item;
}
}).filter((result) => result !== undefined)
)
);
};
console.log(getResult(wantedData, bigArray))
<script>
const wantedData = [1235, 98523, 97766];
const bigArray = [{
bigArrayId: 1111,
Tables: [{
TableId: 11,
TableName: 'loramIpsum',
myDatas: [{
ID: 1234,
title: 'title1',
},
{
ID: 1235,
title: 'title2',
},
],
}, ],
},
{
bigArrayId: 674665,
Tables: [{
TableId: 87545,
TableName: 'table2',
myDatas: [{
ID: 98523,
title: 'mylasttitle',
},
{
ID: 24134,
title: 'alex',
},
{
ID: 97766,
title: 'mylastdata',
},
],
}, ],
},
];
</script>
Any help please ? Can I do it with recursive function ?
I think you need to solve this problem in two steps:
First, create a flat array of tables
Then filter the array by conditions
const bigArray=[{bigArrayId:1111,Tables:[{TableId:11,TableName:"loramIpsum",myDatas:[{ID:1234,title:"title1"},{ID:1235,title:"title2"}]}]},{bigArrayId:674665,Tables:[{TableId:87545,TableName:"table2",myDatas:[{ID:98523,title:"mylasttitle"},{ID:24134,title:"alex"},{ID:97766,title:"mylastdata"}]}]}];
const wantedData = [1235, 98523, 97766];
const flatTables = bigArray.flatMap(({ Tables }) =>
Tables.flatMap(({ myDatas, TableId, TableName }) =>
myDatas.map((data) => ({ ...data, TableId, TableName })) ));
const result = flatTables.filter(({ ID }) => wantedData.includes(ID));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I think if you do it something like this you'll be able to map after you've found the right things rather than mapping everything and then filtering that result:
const bigArray = [{ bigArrayId: 1111, Tables: [{ TableId: 11, TableName: 'loramIpsum', myDatas: [{ ID: 1234, title: 'title1', }, { ID: 1235, title: 'title2', }, ], }, ], }, { bigArrayId: 674665, Tables: [{ TableId: 87545, TableName: 'table2', myDatas: [{ ID: 98523, title: 'mylasttitle', }, { ID: 24134, title: 'alex', }, { ID: 97766, title: 'mylastdata', }, ], }, ], }, ];
const wantedData = [1235, 98523, 97766];
const wanted_set = new Set(wantedData);
const push_concat = (arr1, arr2) => {
for(let i = 0; i < arr2.length; i++)
arr1.push(arr2[i]);
return arr1;
};
const res = bigArray.reduce(
(acc, { Tables }) =>
push_concat(acc,
Tables.flatMap(({ TableId, TableName, myDatas }) =>
myDatas
.filter(({ ID }) => wanted_set.has(ID))
.map(({ ID, title }) => ({ ID, title, TableId, TableName }))
)
),
[]
);
console.log(res);

Search for value contained in array of objects in property of object contained in array

can someone help me with this?
I need a function that given a fieldID, searchs within objects and returns the objectID that fieldID is in.
const objects = [
{
objectID: 11,
fields: [
{ id: 12, name: 'Source ID' },
{ id: 12, name: 'Source ID' },
],
},
{objectID: 14,
fields: [
{ id: 15, name: 'Creator' },
],},
{objectID: 16,
fields: [
{ id: 17, name: 'Type' },
{ id: 18, name: 'Name' },
{ id: 19, name: 'Description' },
],},
];
SOLVED:
Got it working like this:
const getObjectID = fieldId => {
for (const object of objects) {
if (object.fields.find(field => field.id === fieldId)) {
return object.objectID;
}
}
};
This will work:
const getObjectId = (fieldID) => {
const object = objects.find(object => object.fields.find(field => field.id === fieldID )!== undefined)
if(object) return object.objectID;
return null
}
Using the find array method:
const objects = [
{ objectId: 1, fields: ["aaa"] },
{ objectId: 2, fields: ["bbb"] },
{ objectId: 3, fields: ["ccc"] },
];
const getObjectId = (id) => objects.find(object.objectId === id);
console.log(getObjectId(2));
// { objectId: 2, fields: ["bbb"] }
Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

Categories

Resources