Given array of parameters, make array from array of objects - javascript

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
);

Related

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);

Create new array of objects based on two arrays in Javascript

I want to get the array of objects created from two simple arrays:
const array1 = [20, 2, 35, 86]
const array2 = [8, 86, 15, 23, 35, 44]
The expected result:
const result = [
{ id: 20, value: false },
{ id: 2, value: false },
{ id: 35, value: true },
{ id: 86, value: true },
];
The array1 length is the one that matters. So I need to find matched values in both arrays as showed in the expected result.
Thank you very much for your help.
You can combine map with includes:
array1.map(i => ({id: i, value: array2.includes(i)}))
Should be simple. Loop through the first array using Array.map & return an object.
const array1 = [20, 2, 35, 86]
const array2 = [8, 86, 15, 23, 35, 44]
const result = array1.map(i => ({ id: i, value: array2.includes(i) }))
console.log(result)
Create a set from the second array:
const a2set = new Set(array2);
then map your first array:
array1.map(v1 => ({id:v1, value: a2set.has(v1)}))
Start a loop against first array and check if that element exists in second array or not.
If element exists push it to array containing objects with flag true or else as false.
const array1 = [20, 2, 35, 86]
const array2 = [8, 86, 15, 23, 35, 44]
var objArray = []
array1.forEach(function(elem){
objArray.push({
id : elem,
value : array2.indexOf(elem) != -1 ? true : false
});
});
console.log(objArray);
You can use array indexOf to find if the item is inside the second array.
const array1 = [20, 2, 35, 86];
const array2 = [8, 86, 15, 23, 35, 44];
let output = [];
array1.forEach((number) => {
output.push({
id: number,
value: array2.indexOf(number) !== -1
});
});
console.log(output);
Try a simple for loop:
const array1 = [20, 2, 35, 86];
const array2 = [8, 86, 15, 23, 35, 44];
var res = [];
for (var i = 0; i < array1.length; i++) {
if (array2.includes(array1[i])) {
res.push({ id: array1[i], value: true });
} else {
res.push({ id: array1[i], value: false });
}
}
console.log(res);
Try the following. If performance is important, or if the arrays might include a large amount of elements, I'd consider using sets for better lookup performance.
const array1 = [20, 2, 35, 86]
const array2 = [8, 86, 15, 23, 35, 44]
const result = array1.map(element => {
return {
id: element,
value: array2.includes(element)
};
})

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);

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

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});

Categories

Resources