How can I make a JS object from a JS array? - javascript

I have this code which draws a chart: (the needed library is included)
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
theme: "theme2",//theme1
title:{
text: "Basic Column Chart - CanvasJS"
},
animationEnabled: true, // change to true
data: [
{
// Change type to "bar", "area", "spline", "pie",etc.
type: "column",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
}
</script>
All fine. those inputs are as test. Now I need to make my real inputs. I have two JS arrays like these:
var numbers = [10, 585, 563, 24, 4, 486, 123, 458];
var names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'];
Does anybody how can I make something like below from my two arrays?
{ label: "John", y: 10 },
{ label: "Jack", y: 585 },
{ label: "Ali", y: 563 },
.
.
.

Possible solution using Array#map. I assume that both arrays have the same length.
var numbers = [10, 585, 563, 24, 4, 486, 123, 458],
names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'],
res = names.map((v,i) => Object.assign({}, {label: v, y: numbers[i]}));
console.log(res);

const numbers = [10, 585, 563, 24, 4, 486, 123, 458];
const names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'];
const r = names.map((x,i) => { return {label: x, y: numbers[i]}})
console.log(JSON.stringify(r, null, 2))

In case you are unfamiliar with the ECMAScript 6 versions answered above, you can use this slightly outdated syntax as well:
var numbers = [10, 585, 563, 24, 4, 486, 123, 458];
var names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'];
var result = names.map(function(value, index) {
return { label: value, y: numbers[index] };
});

You can do this:
var numbers = [10, 585, 563, 24, 4, 486, 123, 458];
var names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'];
var res = names.map((val,i)=>{
return {label:val, y:numbers[i]};
});
console.log(res);

Or shorter version:
var numbers = [10, 585, 563, 24, 4, 486, 123, 458],
names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'],
res = names.map((v,i) => ({label: v, y: numbers[i]}));
console.log(res);

var numbers = [10, 585, 563, 24, 4, 486, 123, 458];
var names = ['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter']
var obj = []
for (var i in names) {
obj[names[i]] = numbers[i];
}
Edit: Nevermind, should have read the question more thoroughly. I thought you wanted to be able to address the integer values as such:
obj.John == 10;

Using lodash could be more readable:
_.zipWith([10, 585, 563, 24, 4, 486, 123, 458],
['John', 'Jack', 'Ali', 'martin', 'ejy', 'Farid', 'Gordon', 'Peter'],
(y, label) => {label: label, y: y});

Related

filtering array of objects in react not working

I have an array of objects like below:
0: {Id: 1, name: 'xyz', pqID: 10, pqType: null}
1: {Id: 2, name: 'abc', pqID: 15, pqType: null}
2: {Id: 3, name: 'wer', pqID: 16, pqType: null}
3: {Id: 4, name: 'uyt', pqID: 18, pqType: null}
4: {Id: 5, name: 'qwe', pqID: 22, pqType: null}
5: {Id: 6, name: 'ert', pqID: 25, pqType: null}
I want objects of pqID and 10 and 15. Below is what I am trying which is giving empty array:
const newUsers = arr.filter(
(user) => user.pqID == 10 && user.pqID == 15
);
console.log(newUsers);
You could try that, with full array function syntax:
const newUsers = arr.filter(
(user) => {return [10, 15].includes(user.pqID)}
);
Or the minified version, without parentheses and curly brackets:
const newUsers = arr.filter(user => [10, 15].includes(user.pqID));
Note the || operator
var arr =
[{Id: 1, name: 'xyz', pqID: 10, pqType: null},
{Id: 2, name: 'abc', pqID: 15, pqType: null},
{Id: 3, name: 'wer', pqID: 16, pqType: null},
{Id: 4, name: 'uyt', pqID: 18, pqType: null},
{Id: 5, name: 'qwe', pqID: 22, pqType: null},
{Id: 6, name: 'ert', pqID: 25, pqType: null}]
const newUsers = arr.filter(
(user) =>
user.pqID == 10 || user.pqID == 15 // note ||
);
console.log(newUsers)

How to calculate and create new object value from two different arrays in Javascript

var array1 = [{issueCount: 16, failCount: 38, id: 1},
{issueCount: 15, failCount: 37, id: 2},
{issueCount: 15, failCount: 34, id: 3}];
var array2 = [{id: 1, totalAttempts: 57},
{id: 2, totalAttempts: 59},
{id: 3, totalAttempts: 67},
{id: 4, totalAttempts: 59}];
I have two arrays. From the above arrays, I need to calculate failure Percentage using the (array1. fail count/array2.totalAttempts) * 100 [id is common between two arrays]. And the final array wants in the below format.
outputArray = [{id: 1, issueCount: 16, failCount: 38, percentage: 66.66},
{id: 2, issueCount: 15, failCount: 37, percentage: 62.71},
{id: 3, issueCount: 15, failCount: 34, percentage: 50.74}];
Thanks in advance.
You can achieve this with a simple for loop.
Just check if the id exists in the second array, if so make your calculations.
const array1 = [{issueCount: 16, failCount: 38, id: 1},
{issueCount: 15, failCount: 37, id: 2},
{issueCount: 15, failCount: 34, id: 3}];
const array2 = [{id: 1, totalAttempts: 57},
{id: 2, totalAttempts: 59},
{id: 3, totalAttempts: 67},
{id: 4, totalAttempts: 59}];
const outputArray = [];
array1.forEach(i1 => {
const i2 = array2.find(i => i.id === i1.id);
if(i2) {
outputArray.push({
id: i1.id,
issueCount: i1.issueCount,
failCount: i1.failCount,
percentage: (i1.failCount / i2.totalAttempts) * 100
});
}
});
console.log(outputArray)
You can do:
const array1 = [{issueCount: 16, failCount: 38, id: 1},{issueCount: 15, failCount: 37, id: 2},{issueCount: 15, failCount: 34, id: 3}]
const array2 = [{id: 1, totalAttempts: 57},{id: 2, totalAttempts: 59},{id: 3, totalAttempts: 67},{id: 4, totalAttempts: 59}]
const mergedArrays = Object.values([...array1, ...array2].reduce((a, c) => (a[c.id] = { ...a[c.id], ...c }, a), {}))
const outputArray = mergedArrays
.filter(o => o.issueCount && o.totalAttempts)
.map(({ id, issueCount, failCount, percentage, totalAttempts }) => ({
id,
issueCount,
failCount,
percentage: Math.round(failCount / totalAttempts * 100 * 100) / 100
}))
console.log(outputArray)
Thank you all for your posts. I have also find the solution below.
outputArray = [];
array1.forEach(function(dataItem1, idx) {
var array2Items = array2[idx];
var outputItems = {};
if (dataItem1 && array2Items){
if(dataItem1.id == array2Items.id){
outputItems.id = dataItem1.id;
outputItems.issueCount = dataItem1.issueCount;
outputItems.failCount = dataItem1.failCount;
outputItems.percentage = ((dataItem1.failCount/array2Items.totalAttempts)*100).toFixed(2);
outputArray.push(outputItems);
}
}
});
console.log(outputArray);

Given array of parameters, make array from array of objects

I have this array:
course_ids: [11, 70, 3]
And this array of objects:
arr: [{
course_id: 11,
course_hour_id: 56,
name: 'John',
},
{
course_id: 70,
course_hour_id: 72,
name: 'Lily',
},{
course_id: 3,
course_hour_id: 12,
name: 'Mike',
}]
Given these two, I want to make an array of course_hour_ids: [56, 72, 12]
How can I do that using React.js?
At first filter then map
let objArray = [
{
course_id: 11,
course_hour_id: 56,
name: 'John',
},
{
course_id: 70,
course_hour_id: 72,
name: 'Lily',
},
{
course_id: 3,
course_hour_id: 12,
name: 'Mike',
}
];
let course_ids = [11, 70, 3];
let result = objArray.filter(array => course_ids.some(filter => filter == array.course_id)).map(a => a.course_hour_id);
console.log(result);
You colud filter initial array and then map the result array on course_hour_id like:
let arr = [
{
course_id: 11,
course_hour_id: 56,
name: 'John',
},
{
course_id: 70,
course_hour_id: 72,
name: 'Lily',
},{
course_id: 3,
course_hour_id: 12,
name: 'Mike',
}
]
let course_ids = [11, 70, 3];
let res = arr.filter(el => {
return course_ids.includes(el.course_id);
})
console.log(res.map(el => el.course_hour_id))
const course_ids = [11, 70, 3];
const arr = [{
course_id: 11,
course_hour_id: 56,
name: 'John',
},
{
course_id: 70,
course_hour_id: 72,
name: 'Lily',
}, {
course_id: 3,
course_hour_id: 12,
name: 'Mike',
}
];
const result = arr.map(x => {
if (course_ids.includes(x.course_id))
return x.course_hour_id
});
console.log(result)
No need to use .filter
course_ids
.map(course_id =>
arr.find(arrItem =>
arrItem.course_id === course_id)
?.course_hour_id);
The above solutions uses optional chaining. If you don't use that you can write:
course_ids
.map(course_id =>
arr.some(arrItem =>
arrItem.course_id === course_id)
? arr.find(arrItem =>
arrItem.course_id === course_id).course_hour_id
: null
);

convert nested array to single object with key values Javascirpt

I have an array that contains nested arrays.
The nested array can contain multiple objects.
const axisChoiceLoop = _.map(groupByAxisChoice)
output:
[
0: [ {age: 15, count: 242, role: "JW"}] // length 1
1: [ {age: 21, count: 995, role: "JW"} , {age: 21, count: 137, role: "SW"} ] // length 2
2: [ {age: 25, count: 924, role: "JW"}, {age: 25, count: 455, role: "SW"}, {age: 25, count: 32, role: "EW"} ]
]
I would like the nested arrays to be single objects, using their role as the key, and count as the value
expected output would look like this
[
{age :15, JW: 242},
{age: 21, JW:995, SW: 137},
{age: 25, JW: 924, SW: 445, EW: 32}
]
Edit: I have tried the following code
const result = groupByAxisChoice.reduce(
(obj, item) => Object.assign(obj, { [item.role]: item.count }),
{},
)
Which outputs: { undefined: undefined }
Figured it out...
const result = groupByAxisChoice.map(items =>
items.reduce((obj, item) => Object.assign(obj, { age: item.age, [item.role]: item.count }), {}),
)
This is what I ended up with, I know it's not optimized:
var arr = [
[ {age: 15, count: 242, role: "JW"}], // length 1
[ {age: 21, count: 995, role: "JW"} , {age: 21, count: 137, role: "SW"} ], // length 2
[ {age: 25, count: 924, role: "JW"}, {age: 25, count: 455, role: "SW"}, {age: 25, count: 32, role: "EW"} ]
];
var newArr = [];
arr.forEach(function(a) {
var ob = {age: a[0].age};
a.forEach(d => ob[d.role] = d.count);
newArr.push(ob);
});
I'll try to make it better (i don't know how to use underscore.js)...
another solutions
const b = a.map(item => {
return item.reduce((arr,curr) => {
return {
...arr,
['age']: curr['age'],
[curr['role']]: curr['count'],
}
}, {})
})
console.log(b)

Removing dynamic keys from array of objects

This previous question comes closest to what I am curious of. I've tried several variations of indexOf() and filter() to no success
I have an arrays of objects (exampleDat):
[{id:1, value:"100", name:"dog", D1: 10, D2: 67, D3: 33},
{id:2, value:"200", name:"cat", D1: 66, D2: 41, D3: 34},
{id:3, value:"300", name:"fish", D1: 23, D2: 45, D3:},
{id:4, value:"400", name:"mouse", D1: 13, D2: 55, D3:},
{id:5, value:"500", name:"snake", D1: 7, D2: 9, D3:}]
In a different function, I return an array of which of these 'keys' I need. This array changes dynamically, so its not possible to type them all out. For example any of the following examples are viable,
useThese1 = ['D1','D2'] //Want exampleDat returned with only these key,value 'columns' returned
useThese2 = ['id','D1','D2','D3'] //Want exampleDat return with only these key,value 'columns' returned
useThese3 = ['value','D2','D3'] //Want exampleDat returned with only these key,value 'columns' returned
So I need to dynamically map the values in a useThese array to the exampleDat array
If I knew the exact columns, I could hand type it ala:
exampleDat.map(d => {return {D1: d.D1, D2: d.D2}})
But I need something like:
dat.map(d => useThese1.map(g => {return {something?}}) ???
In R, it would simply and easily be exampleDat[,colnames(exampleDat) %in% useThese1]
You could map the new keys.
const
mapWith = (array, keys) => array.map(o => Object.fromEntries(keys.map(k => [k, o[k]]))),
data = [{ id: 1, value: "100", name: "dog", D1: 10, D2: 67, D3: 33 }, { id: 2, value: "200", name: "cat", D1: 66, D2: 41, D3: 34 }, { id: 3, value: "300", name: "fish", D1: 23, D2: 45, D3:97}, { id: 4, value: "400", name: "mouse", D1: 13, D2: 55, D3:98}, { id: 5, value: "500", name: "snake", D1: 7, D2: 9, D3:99}],
result1 = mapWith(data, ['D1', 'D2']),
result2 = mapWith(data, ['id', 'D1', 'D2', 'D3']),
result3 = mapWith(data, ['value', 'D2', 'D3']);
console.log(result1);
console.log(result2);
console.log(result3);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Object.fromEntries are relatively recent, but easily polyfilled.
Here is my solution. This uses the ES5 Javascript functions
const selectKeys = (keys, data) => {
return data.map(item => keys.reduce((prev, key) => {
prev[key] = item[key]
return prev
}, {}))
}
const selData1 = selectKeys(useThese1, data)
const selData2 = selectKeys(useThese2, data)
const selData3 = selectKeys(useThese3, data)
You can do something like this
const arr = [
{ id: 1, value: "100", name: "dog", D1: 10, D2: 67, D3: 33 },
{ id: 2, value: "200", name: "cat", D1: 66, D2: 41, D3: 34 },
{ id: 3, value: "300", name: "fish", D1: 23, D2: 45, D3: 34 },
{ id: 4, value: "400", name: "mouse", D1: 13, D2: 55, D3: 34 },
{ id: 5, value: "500", name: "snake", D1: 7, D2: 9, D3: 34 }
];
function dynamicFilter(data, requiredKeys) {
return data.map((item) => {
const result = {};
requiredKeys.forEach(key => result[key] = item[key]);
return result;
});
}
console.log(dynamicFilter(arr, ['D1','D2']));
console.log(dynamicFilter(arr, ['id','D1','D2','D3']));
You can do something like this:
const arr = [{id:1, value:"100", name:"dog", D1: 10, D2: 67, D3: 33}, {id:2, value:"200", name:"cat", D1: 66, D2: 41, D3: 34}, {id:3, value:"300", name:"fish", D1: 23, D2: 45, D3:11}, {id:4, value:"400", name:"mouse", D1: 13, D2: 55, D3:11}, {id:5, value:"500", name:"snake", D1: 7, D2: 9, D3:11}];
const useThese1 = ['D1','D2'];
const useThese2 = ['id','D1','D2','D3'];
const useThese3 = ['value','D2','D3'];
const getResult = (keys) => arr.map(v => keys.reduce((a, c) => (a[c] = v[c], a), {}));
[useThese1, useThese2, useThese3].forEach(v => console.log(getResult(v)));
Here's an imperative way to do it. It could be shortened with ES6 array methods.
let exampleDat = [
{id:1, value:"100", name:"dog", D1: 10, D2: 67, D3: 33},
{id:2, value:"200", name:"cat", D1: 66, D2: 41, D3: 34},
{id:3, value:"300", name:"fish", D1: 23, D2: 45, D3: 8},
{id:4, value:"400", name:"mouse", D1: 13, D2: 55, D3: 8},
{id:5, value:"500", name:"snake", D1: 7, D2: 9, D3: 8}
],
useThese1 = ['D1','D2']
function getColumns(data, useWhich){
let result = [];
for(let row of data){
let keys = Object.keys(row);
let filteredRow = {};
for(let key of keys){
if(useWhich.includes(key)){
filteredRow[key] = row[key];
}
}
result.push(filteredRow);
}
return result;
}
console.log(getColumns(exampleDat, useThese1));
Here's a "for dummies" version of the accepted answer.
(The more verbose variable names helped me understand how the algorithm works.)
const
selectColumns = (unfilteredData, colsToKeep) =>
unfilteredData.map(row =>
Object.fromEntries(colsToKeep.map( col => [col, row[col]] )
)
),
data = [
{ id: 1, value: "100", name: "dog", D1: 10, D2: 67, D3: 33 },
{ id: 2, value: "200", name: "cat", D1: 66, D2: 41, D3: 34 },
{ id: 3, value: "300", name: "fish", D1: 23, D2: 45, D3:97 },
{ id: 4, value: "400", name: "mouse", D1: 13, D2: 55, D3:98 },
{ id: 5, value: "500", name: "snake", D1: 7, D2: 9, D3:99 }
],
colNames1 = ['D1', 'D2'],
result1 = selectColumns(data, colNames1);
console.log(result1);

Categories

Resources