2-dimensional array to object (JavaScript) - javascript

I have an array, that holds a large number of two-dimensional arrays:
var myArray = [
[2260146,2334221,"copy"],
[1226218,2334231,"copy"],
[2230932,-1,"copy"],
[2230933,-1,"copy"],
[2230934,-1,"copy"]
]
I need to convert this array into an object of the following form to send it as JSON:
var json = [
{
"s_id": 2260146,
"t_id": 2334221,
"type": "copy"
},
{
"s_id": 1226218,
"t_id": 2334231,
"type": "copy"
},
{
"s_id": 12,
"t_id": -1,
"type": "copy"
}
]
("s_id" should be myArray[0][0], "t_id myArray[0][1], and "type" myArray[0][2] and so on.)
How can I get the array in the desired form? Thanks in advance.

json = myArray.map(function(x) {
return {
"s_id": x[0],
"t_id": x[1],
"type": x[2]
}
})
Be aware that map is not supported in IEs < 9.

You could destructure the parameter in map and use Shorthand property names:
const myArray=[[2260146,2334221,"copy"],[1226218,2334231,"copy"],[2230932,-1,"copy"],[2230933,-1,"copy"],[2230934,-1,"copy"]]
const output = myArray.map(([s_id, t_id, type]) => ({ s_id, t_id, type }))
console.log(output)

Try with:
var length = myArray.length,
json = [];
for ( var i = 0; i < length; i++ ) {
var subArray = myArray[i],
item = {
s_id: subArray[0],
t_id: subArray[1],
type: subArray[2]
};
json.push(item);
}

How to traverse through the following structure from 2D array
weekearn,monthearn is variable containing array of objects.
I need loop because I don't know the number of products
const stackdata = {
datasets:[{
data: weekearn,
label: 'Product 1',
backgroundColor: 'rgb(255, 87, 51)',
borderColor: 'rgb(255, 99, 132)',
},
{
data: monthearn,
label: 'Product 2',
backgroundColor: 'rgb(155, 87, 51)',
borderColor: 'rgb(255, 99, 32)',
}
]
};

Related

JavaScript, filter array of objects by a specific key's value

I am trying to find the best way to filter my array of objects with specific key's string. Basically what I am trying to achieve is to get the objects which contain "Type":"Blue". Here is my data:
[
{
"data": [
{}
],
"Name": "1",
"Type": "Blue"
},
{
"data": [
{}
],
"Name": "2",
"Type": "Red"
},
{
"data": [
{}
],
"Name": "3",
"Type": "Blue"
}
]
You could use the filter() method. See the snippet below, as well as a definition of the method from MDN:
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
const data = [
{
data: [{}],
Name: "1",
Type: "Blue"
},
{
data: [{}],
Name: "2",
Type: "Red"
},
{
data: [{}],
Name: "3",
Type: "Blue"
}
];
const filteredData = data.filter((item) => item.Type === "Blue");
console.log(filteredData);
You can use the Array.prototype.filter() method.
arr.filter(obj => obj.Type == 'Blue');
will give you the array containing only the objects with type Blue.
If I understood your requirement correctly, You have a string "Type: Blue" and based on this string you have to filtered out the data array dynamically based on the key as Type and value as Blue. If Yes, Here you go :
const str = "Type: Blue";
const splittedStr = str.split(':');
const data = [
{
Name: "1",
Type: "Blue"
},
{
Name: "2",
Type: "Red"
},
{
Name: "3",
Type: "Blue"
}
];
const filteredData = data.filter((item) => item[splittedStr[0]] === splittedStr[1].trim());
console.log(filteredData);

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

How to push the first value of a list of arrays to object?

I have a nested array and want to push the first item from one of the arrays to state,
the Parent Array like this
"options": [
{
"id": 76,
"label_en": "Disk Storage",
"type": "text",
"product_id": 20,
"values": [
{
"id": 133,
"name_en": "32 GigByte",
"display_value": null,
"randam_key": "8596598ED", // this the target value I want to save
"option_id": 76
},
{
"id": 134,
"name_en": "16 GigByte",
"display_value": null,
"randam_key": "895454HG",
"option_id": 76
}
]
},
{
.....
}
]
every object from the "options - Parent" Array has a values array,
and every object of the values array has a randam_key
I want to save the first random key value from every object of the values array,
at the same time, i have a function that's store all values into a state to be like
//result
bodyQuery = {
"product_id": 20,
"values": {
"randam_key1": "895454HG",
"randam_key2": "FFJFOF568",
"randam_key3": "FDVHFDVD566"
}
}
const getUpdatedPrice = (randam_key: string, handleKey: string) => {
setBodyQuery((prevState) => ({
...prevState,
values: {
...prevState.values,
[handleKey]: randam_key,
},
}));
};
So what I tried is to get the keys 'Check the Live Code at the bottom', but i don't know how can I call getUpdatedPrice() to save the data as expected when the screen mounted.
the second case I have that saves the random keys after iterated the arrays and when I press to any item i call the getUpdatedPrice()
and this works very well but i need to do this behavior when screen mounted useEffect()!
#Second Case - Work as expected
{options.map((option) => {
....
{option.values.map((value: valueOptionProp, index) => {
// button
onPress={()=> getUpdatedPrice(
value.randam_key,
'randam_key' + (options.indexOf(option) + 1),
);
}
})}
})}
live code
{/* let optionsArr=[]
options.map((option) => {
optionsArr.push(option.values);
}
*/}
// the result of the above code is
optionsArr = [
[
{
display_value: null,
id: 133,
name_en: '32 GigByte',
option_id: 76,
randam_key: '8596598ED',
},
{
display_value: null,
id: 134,
name_en: '16 GigByte',
option_id: 76,
randam_key: '895454HG',
},
],
[
{
display_value: '#FFF',
id: 135,
name_en: 'Ù‹White',
option_id: 77,
randam_key: 'FGFFDCF54',
},
{
display_value: '#85FD',
id: 136,
name_en: 'Golden',
option_id: 77,
randam_key: 'FFJFOF568',
},
],
[
{
display_value: 'Url Image Here',
id: 137,
name_en: 'image 1',
option_id: 78,
randam_key: 'HGHVDF84585',
},
{
display_value: 'Url Image Here',
id: 138,
name_en: 'Image 2',
option_id: 78,
randam_key: 'FDVHFDVD566',
},
],
];
let first_randomKey = optionsArr.map(val=>val[0].randam_key);
console.log(first_randomKey);
#Edit
I try it like this and it works well!
If there any other solutions please let me know!
useEffect(() => {
let optionsArr: any[] = [];
item.options.map((option) => {
optionsArr.push(option.values);
});
let first_randomKey = optionsArr.map((val) => val[0].randam_key);
let keys = first_randomKey.map((_itemKeys) => {
getUpdatedPrice(
_itemKeys,
'randam_key' + (first_randomKey.indexOf(_itemKeys) + 1),
);
});
Promise.all(keys).then(() => {
isUpdated.current = true;
});
}, [item.options]);
useEffect(() => {
if (isUpdated.current) {
console.log('bodyQuery', bodyQuery);
}
}, [bodyQuery]);
There are a number of inconsistencies and inefficiencies in your final code, mostly around your use of Array.prototype.map().
Array.prototype.map() returns a new array, so declaring optionsArr and then using map() to push to it is redundant. You use it correctly in the next line however, when you assign first_randomKey by calling map() on the aforementioned optionsArr.
In your final map() call you are manually finding the index of the current iterated _itemsKeys but this is unnecessary as map() provides this for you as the second parameter of the callback. Again, elsewhere in your question you pass the index, but even then you aren't using it but manually finding the index.
The main inefficiency is that you using three map() calls for what could be achieved with one, here using destructuring assignment to access desired property, and leveraging the implicitly passed index parameter provided by map().
const keys = item.options.map(({ values: [{ randam_key }] }, index) =>
getUpdatedPrice(randam_key, 'randam_key' + (index + 1)));
or without destructuring
const keys = item.options.map((option, index) => {
const randam_key = option.values[0].randam_key;
return getUpdatedPrice(randam_key, 'randam_key' + (index + 1));
});
const item = { "options": [{ id: 1, values: [{ id: 133, randam_key: "8596598ED" }, { id: 134, randam_key: "895454HG", }] }, { id: 1, values: [{ id: 135, randam_key: 'FGFFDCF54', }, { id: 136, randam_key: 'FFJFOF568', },] }, { id: 1, values: [{ id: 137, randam_key: 'HGHVDF84585', }, { id: 138, randam_key: 'FDVHFDVD566', },] }] }
const getUpdatedPrice = async (key, indexedKey) => {
return [key, indexedKey]
}
const keys = item.options.map(({ values: [{ randam_key }] }, index) =>
getUpdatedPrice(randam_key, 'randam_key' + (index + 1)));
Promise.all(keys).then((result) => {
console.log(result)
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

Converting object to array format with Javascript

I have a data object like this:
{
"backgroundColor": [
"#E5700F",
"#DA830F",
],
"data": [
26,
10,
],
}
I want to change the format to be like this:
[
{
"backgroundColor": "#E5700F",
"data": 26,},
{
"backgroundColor": "#DA830F",
"data": 10,},
]
how to achieve it using javascript?
You could do this:
const old = {
backgroundColor: ["#E5700F", "#DA830F"],
data: [26, 10],
};
let newArray = [];
old.backgroundColor.forEach((item, idx) => {
newArray.push({ backgroundColor: item, data: old.data[idx] });
});
This could work if the object is not dynamic.
let data = {
"backgroundColor": [
"#E5700F",
"#DA830F",
],
"data": [
26,
10,
],
};
let result = data.backgroundColor.map(function(item, index) {
return {
backgroundColor: item,
data: data.data[index]
}
});
console.log(result);
You can do it like this:
Note that the array's length may not be equal, so it is best to consider this in your data conversion routine.
let sourceData = {
"backgroundColor": [
"#E5700F",
"#DA830F",
],
"data": [
26,
10,
],
};
let result = [];
let length = Math.max(sourceData.backgroundColor.length, sourceData.data.length);
for (let index = 0; index < length; index++) {
result.push({
"backgroundColor": sourceData.backgroundColor[index],
"data": sourceData.data[index]
})
}
console.log(result);

Merge arrays of object into single array of object

I am looking for merge arrays of object into single array of object and append key of object to each key from inner object's key
I have object like
var myObj = {
"Details": [{
"car": "Audi",
"price": 40000,
"color": "blue"
},
{
"car": "BMW",
"price": 35000,
"color": "black"
}
],
"Accounts": [{
"Total": 2000
},
{
"Total": 3000
}
]
}
and Keys and objects length is not known, I want to merge it like
[
{
"Detailscar": "Audi",
"Detailsprice": 40000,
"Detailscolor": "blue",
"AccountsTotal": 2000
},
{
"Detailscar": "BMW",
"Detailsprice": 35000,
"Detailscolor": "black",
"AccountsTotal": 3000
}
]
I have tried with Ramda mergeAll but it is not working in my case as it only merge objects
here is what I tried
var mergedArray = []
R.mapObjIndexed((instance, instanceName) => {
mergedArray.push(R.map((innerObj) => {
var customObject = {};
R.forEach((key) => {
customObject[`${instanceName}${key}`] = innerObj[key]
}, Object.keys(innerObj))
return customObject;
}, instance))
}, myObj)
I am trying add to each modified object to the mergerArray array but it adding for each iteration and finally, it is creating 2 arrays
mergedArray is still creating two different arrays with the key of the object to be appended to the properties of the object but I want it to be merged in the single array of object.
I am missing something. What should I do to resolve this issue?
Suggest some help.
Use Array.prototype.map and index as second parameter passsed to its callback to get element from Account object
const data = {
"Details": [
{
"car": "Audi",
"price": 40000,
"color": "blue"
},
{
"car": "BMW",
"price": 35000,
"color": "black"
},
{
"car": "Porsche",
"price": 60000,
"color": "green"
}
],
"Accounts": [
{
"Total": 2000
},
{
"Total": 3000
},
{
"Total": 3000
}
]
};
const mergeCarData = ({ Details, Accounts} = {}) => {
return Details.length === Accounts.length ? Details.map(({ car, price, color}, idx) => ({
Detailscar: car,
Detailsprice: price,
Detailscolor: color,
AccountsTotal: Accounts[idx].Total
})) : [];
};
console.log(mergeCarData(data));
In plain Javascript, you could iterate the keys of the given object and iterate the arrays and build a new object out of the inner properties with a new key.
var object = { Details: [{ car: "Audi", price: 40000, color: "blue" }, { car: "BMW", price: 35000, color: "black" }], Accounts: [{ Total: 2000 }, { Total: 3000 }] },
result = Object.keys(object).reduce(function (returnValue, parentKey) {
object[parentKey].forEach(function (currentObj, i) {
returnValue[i] = returnValue[i] || {};
Object.keys(currentObj).forEach(function (childKey) {
returnValue[i][parentKey + childKey] = currentObj[childKey];
});
});
return returnValue;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Well, it's not pretty, but you could do something like this:
const convert = pipe(
mapObjIndexed((val, name) => pipe(
map(toPairs),
map(map(([prop, propVal]) => objOf(name + prop, propVal))),
map(mergeAll),
)(val)),
values,
apply(zipWith(merge))
)
You can see this in action on the Ramda REPL.
Here you go, another option. I pulled a renameBy function from ramda recipe list. You can combine all the stuff on to one line if you want.
// https://github.com/ramda/ramda/wiki/Cookbook#rename-keys-of-an-object
const renameBy = R.curry((fn, obj) => R.pipe(R.toPairs, R.map(R.adjust(fn, 0)), R.fromPairs)(obj));
let convertNames = R.mapObjIndexed((value, key)=> {
return R.map(renameBy(R.concat(key)), value)
})
let mergeUp = R.pipe(R.values, R.reduce(R.mergeDeepLeft,[]), R.values)
let convert = R.pipe(convertNames, mergeUp)
convert(myObj)

Categories