How to get element with key in list of dicts - javascript

I have a list of objects like this:
let colors = [
{
id: 0,
color: "green",
},
{
id: 1,
color: "blue",
},
{
id: 2,
color: "orange",
},
];
What is the best way (most optimized) to get an element with id=1... is there a way to do it without iterating through the list?

Small tip:
Use const instead of let when you're not reassigning values
Try doing the following:
// ✅ good pattern: destructuring. We only use what we need
const myColor = colors.find(({ id }) => id === 1)

You can iterate over the whole array once and create a lookup table if the array is static. Then, lookups can be done in constant time after O(n) preprocessing.
let colors = [
{
id: 0,
color: "green",
},
{
id: 1,
color: "blue",
},
{
id: 2,
color: "orange",
},
];
const lookup = colors.reduce((acc,curr)=>(acc[curr.id] = curr, acc), {});
console.log(lookup[1]);
console.log(lookup[2]);

Related

Generate array into new array

Hi guys i got a complicated case for me
I have 4 array like this
[
{
"Id":1111111,
"OptionName":"Color",
"VariantName":"White"
},
{
"Id":2222222,
"optionName":"Size",
"VariantName":"XL"
},
{
"Id":3333333,
"OptionName":"Color",
"VariantName":"GREEN"
},
{
"Id":4444444,
"optionName":"Size",
"VariantName":"L"
}
]
So i want to merge the ID like
1 on 1, 1 on 2,2 on 1, 2 on 2
The result should be like this, but depend by variant name, so colours merge to size
[
{
"Id":1111111_2222222
...
},
{
"Id":1111111_4444444,
...
},
{
"Id":3333333_2222222,
...
},
{
"Id":3333333_4444444,
...
}
]
I already found how to group them by option Name, but how to merge it?
this is the code how i group them
const filteredVariantCats = variantCats
.map((a) => a.optionName)
.filter(onlyUnique)
.map((optionName) => {
let array = []
return variantCats
.filter((a) => a.optionName === optionName)
.map((a, idx) => {
array.push(a)
return a
})
})
UPDATE RESULT THAT I WANT TO RETURN IS THIS
{
id: null,
combinationStr: a.ID+"_"+b.ID,
name: a.variantName+' ,'+ b.variantName,
hex: '#000',
stock: 0,
price: 0,
priceDiscountType: OPTION.DISCOUNT_TYPE.NONE,
priceDiscount: 0,
weight: 10,
code: '',
attributeCode: 'a',
active: true,
productId: product.id from state,
}
Assume the syntax error and mis-matched cases are just error you make while writing the example and not actual mistakes in your actual code. If I understand correctly, you want to split the array into two groups, colors and sizes. Then generate all combinations between the two. Here is an example of how to do so. Since you mark ... in your expected output, I don't know what you actually expect so can only provide the Id field.
const arr = [
{
Id: 1111111,
OptionName: "Color",
VariantName: "White"
},
{
Id: 2222222,
OptionName: "Size",
VariantName: "XL",
},
{
Id: 3333333,
OptionName: "Color",
VariantName: "GREEN"
},
{
Id: 4444444,
OptionName: "Size",
VariantName: "L",
}
];
const colors = arr.filter(it => it.OptionName == "Color");
const sizes = arr.filter(it => it.OptionName == "Size");
let results = [];
for(let color of colors)
{
for(let size of sizes)
{
results.push({Id: `${color.Id}_${size.Id}`});
}
}
console.log(results);

How to compare two array and push data based on result Angular

I have add my all code below, but important function is patchDataCollection() where i have added push logic for forms.
I want to compare values of both arrayOne and arrayTwo based on below condition and if it matches than it will pass data along with form otherwise it will create an empty form.
Expected output
I have created patchDataCollection() function where i am creating forms based on above condition, but in my case it is patching data to all generated forms
, i want only patch thosa object which are avlbl in arrayTww.
Below condition i wanted to check in arrayOne and arrayTwo.
if arrayOne processTypeId is equal to arrayTwo of makeProcessTypeId And
arrayOne makeLineName is equal to arrayTwo of makeLineName And
arrayOne processTechType is equal to arrayTwo of processTechType than
If all above conditions are met than only dataOne variable will pass along with form.
this.itemTypes().push(this.createContinuousForm(item, dataOne));
else it will create an empty form only without pushing dataOne in form.
this.itemTypes().push(this.createContinuousForm(item));
Const arrayOne = [
{
"makeLineName": "Red",
types : [
{
"processTypeId": 101,
"processTechType": "Batch"
},
{
"processTypeId": 102,
"processTechType": "Batch"
}
]
},
{
"makeLineName": "Blue",
types : [
{
"processTypeId": 103,
"processTechType": "Continuous"
},
{
"processTypeId": 104,
"processTechType": "Batch"
}
]
}
];
Const arrayTwo =
[
{
"makeProcessTypeId": 101,
"makeLineName": "Red",
"processTechType": "Batch",
"avgBct": 23,
"bestBct": 23
},
{
"makeProcessTypeId": 102,
"makeLineName": "Blue",
"processTechType": "Batch",
"avgBct": 45,
"bestBct": 45
},
{
"makeProcessTypeId": 103,
"makeLineName": "Blue",
"processTechType": "Continuous",
"designProcessCapacity": 250,
"minRunLength": 250
}
];
getMakeLineData() {
for (const line of arrayOne) {
const list = line.types;
for (const item of list) {
if (item.processTechType === 'Continuous') {
this.patchDataCollection(item);
} else if (item.processTechType === 'Batch' || item.processTechType === 'Batch-Crunch') {
this.patchDataCollection(item);
}
}
}
}
patchDataCollection(arrayOne) {
if (arrayTwo) {
for (const dataOne of arrayTwo) {
if (arrayOne.makeLineName == dataOne.makeLineName) {
if (arrayOne.processTechType === 'Continuous') {
this.itemTypes().push(this.createContinuousForm(item, dataOne));
}
if (dataOne.processTechType === 'Batch' || dataOne.processTechType === 'Batch-Crunch') {
this.itemTypes().push(this.createBatchForm(item, dataOne));
}
}
}
}
}
createContinuousForm(type, data) {
return this.fb.group({
makeLineName: [type.makeLineName],
processTechType: [type.processTechType],
makeProcessTypeId: [type.processTypeId],
designProcessCapacity: [data.designProcessCapacity ? data.designProcessCapacity : '', [Validators.required]],
minRunLength: [data.minRunLength ? data.minRunLength : '']
});
}
createBatchForm(type, data) {
return this.fb.group({
makeLineName: [type.makeLineName],
processTechType: [type.processTechType],
makeProcessTypeId: [type.processTypeId],
avgBct: [data.avgBct ? data.avgBct : '', [Validators.required]],
bestBct: [data.bestBct ? data.bestBct : '', [Validators.required]]
});
}
itemTypes(): FormArray {
return this.dataCollectionForm.get("items") as FormArray;
}
While I think there are better ways to store the data compared to what the API returns to you, it is certainly possible to compare the two arrays and only use the values that exist in both arrays, given your conditions.
The surrounding object with makeLineName and types in your arrayOne do not contain any valuable information (any information that is not within the types array anyway). You can start here with:
arrayOne.flatMap(i => i.types)
From my perspective the createContinuousForm and createBatchForm functions don't need two parameters. It should be enough if you pass the item from arrayTwo as the only values from arrayOne used in your functions are the one that must match the ones from arrayTwo.
I could see something in this direction working:
const arrayOne = [{
makeLineName: 'Red',
types: [{
processTypeId: '102',
processTechType: 'Batch',
makeLineName: 'Red',
}, ],
},
{
makeLineName: 'Blue',
types: [{
processTypeId: '103',
processTechType: 'Continuous',
makeLineName: 'Blue',
}, ],
},
];
const arrayTwo = [{
makeProcessTypeId: 101,
makeLineName: 'Red',
processTechType: 'Batch',
avgBct: 23,
bestBct: 23,
},
{
makeProcessTypeId: 102,
makeLineName: 'Blue',
processTechType: 'Batch',
avgBct: 45,
bestBct: 45,
},
{
makeProcessTypeId: 103,
makeLineName: 'Blue',
processTechType: 'Continuous',
designProcessCapacity: 250,
minRunLength: 250,
},
];
const simplifiedArrayOne = arrayOne.flatMap(i => i.types);
function createContinuousForm(item) {
console.log({
// if you put this into [], then your makeLineName is an array with one value
makeLineName: item.makeLineName,
processTechType: item.processTechType,
makeProcessTypeId: item.makeProcessTypeId,
designProcessCapacity: [
item.designProcessCapacity ? item.designProcessCapacity : ''
],
});
}
function createBatchForm(item) {
console.log({
makeLineName: item.makeLineName,
processTechType: item.processTechType,
makeProcessTypeId: item.makeProcessTypeId,
avgBct: item.avgBct ? item.avgBct : '',
bestBct: item.bestBct ? item.bestBct : '',
});
}
arrayTwo.filter(entry => {
// .toString() is necessary because your types of processTypeId (string) and makeProcessTypeId (number) are different
const index = simplifiedArrayOne.findIndex(e => e.processTypeId === entry.makeProcessTypeId.toString())
return index > -1 && entry.makeLineName === simplifiedArrayOne[index].makeLineName
}).forEach(item => item.processTechType === 'Continuous' ? this.createContinuousForm(item) : this.createBatchForm(item));
Please take note of the comments within the code. Also, as you're using TypeScript you could use an enum for the processTechType and possibly another one for the makeLineName as well

handle find property in array if undefined

I have this simple code that works. However it feels cheesy and like I am doing something stupid.
So is this how I would handle this if I wanted to be in one line?
let lifeColors = [
{ lives: 1, color: 'lime' },
{ lives: 2, color: 'orange' },
{ lives: 3, color: 'salmon' },
]
let lives = 20;
let color = (lifeColors.find(x => x.lives === lives) || {color: 'white'}).color;
console.log(color)
My inspiration was from this post
JS: Handle with find() property undefined

Insertion sort on an array of objects with javascript

I have this array with objects that look like this
{
n: 15,
color: "red"
}
I am trying to sort it with the below function
async insertionSort() {
let len = this.array.length;
let value;
let i;
let j;
//let current;
// let arr = this.array;
for (i = 0; i < len; i++) {
value = this.array[i].n;
//current = this.array[i];
for (j = i - 1; j > -1 && this.array[j].n > value; j++) {
//arr[j + 1] = arr[j];
// HF.arraySwap(this.array, this.array[j + 1], this.array[j]);
this.array[j + 1] = this.array[j];
}
// arr[j + 1] = value;
HF.arraySwap(this.array, this.array[j + 1], this.array[i]);
await HF.sleep();
}
}
** I cant use array.sort(...) because i am trying to make a visualization of the algorithm, i am using objects in order to change the color of the bars i am rendering on the screen **
When i hit the second for loop i get an error of "Cannot read property 'n' of undefined", when i run it with just numbers it works fine but when i try it with objects it gives the error.I know now i am running out of the array, is there a way i can overcome this and still sort the array of objects? Also, i am using VueJS to display all of this
Try against this.array[i].n write this.array[i][n]
And against this.array[j].n write this.array[j][n]
On the first iteration i=0, you start second loop with value j=i-1 which is -1. Array doesn't contain item with index -1: array[-1] is undefined. As soon as JavaScript can compare variables of different types it works with numbers because comparison of number and undefined won't trigger an error
By the way you can use Array.proototype.sort method, it will look like:
console.log(myArr.sort((a,b) => a.n - b.n))
<script>
const myArr = [
{ n: 1, color: "red" },
{ n: 44, color: "orange" },
{ n: 13, color: "yellow" },
{ n: 8, color: "green" },
{ n: 2, color: "blue" }
];
</script>
Is there any reason why not use sort method like this?:
const arr = [
{ n: 10, color: "red" },
{ n: 20, color: "yellow" },
{ n: 15, color: "black" },
{ n: 7, color: "white" },
{ n: 23, color: "blue" }
];
const ascSorted = arr.sort((a, b) => a.n - b.n);
const descSorted = arr.sort((a, b) => b.n - a.n);
console.log(ascSorted);
// [
// { n: 7, color: "white" },
// { n: 10, color: "red" },
// { n: 15, color: "black" },
// { n: 20, color: "yellow" },
// { n: 23, color: "blue" }
// ];

Is there a way to only show selected property in a json object based on a array

I have the following object
calendarLists = [
{Title: titel1, Color:blue, number:1}
{Title: titel2, Color:green, number:2}]
{Title: titel3, Color:red, number:3}
]
It has alot more property but for simplicity sake ill just show 3 properties. I also have the follow array [Title,number]
Now basing from the array I only want to show object property based on my array. My results should be
results =[{Title: titel1, , number:1},{Title: titel2, , number:2},{Title: titel3, , number:3}]
You could map the wanted properties as objects, collect them to a single object and mapp all objects for a new array.
var calendarLists = [
{ Title: 'titel1', Color: 'blue', number: 1 },
{ Title: 'titel2', Color: 'green', number: 2 },
{ Title: 'titel3', Color: 'red', number: 3 }
],
keys = ['Title', 'number'],
result = calendarLists.map(o => Object.assign(...keys.map(k => ({ [k]: o[k] }))));
console.log(result);
The same with a destructuring assignment and short hand properties.
var calendarLists = [
{ Title: 'titel1', Color: 'blue', number: 1 },
{ Title: 'titel2', Color: 'green', number: 2 },
{ Title: 'titel3', Color: 'red', number: 3 }
],
result = calendarLists.map(({ Title, number }) => ({ Title, number }));
console.log(result);
Your calendarLists has syntax error. You can map this array and filter wanted properties.
calendarLists = [{
Title: 'titel1',
Color: 'blue',
number: 1
},
{
Title: 'titel2',
Color: 'green',
number: 2
},
{
Title: 'titel3',
Color: 'red',
number: 3
}
];
result = calendarLists.map(
calendarList => {
return {
Title: calendarList.Title,
number: calendarList.number
}
}
);
console.log(result);

Categories