convert nested array to single object with key values Javascirpt - javascript

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)

Related

Sort object with array ordering by key name [duplicate]

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed last month.
How can I sort an object, which has an array inside. I need to sort by name in javascript.
My object is:
(4) [{...},{...},{...},{...}]
0: {Age: 10, Name: 'John'}
1: {Age: 25, Name: 'Maria'}
2: {Age: 23, Name: 'Ana'}
3: {Age: 27, Name: 'Pedro'}
The output should be an object like this:
(4) [{...},{...},{...},{...}]
0: {Age: 23, Name: 'Ana'}
1: {Age: 10, Name: 'John'}
2: {Age: 25, Name: 'Maria'}
3: {Age: 27, Name: 'Pedro'}
Sort based on the result of String.prototype.localeCompare (note that Array.prototype.sort also mutates the original array)
const data = [{Age: 10, Name: 'John'},
{Age: 25, Name: 'Maria'},
{Age: 23, Name: 'Ana'},
{Age: 27, Name: 'Pedro'},]
const newData = data.sort((a, b) => a.Name.localeCompare(b.Name));
console.log(newData);

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

finding object in an array

I have an array of and array of objects similar to this :
const oldArray =[
[{'val': 12, 'rank':1},{'val': 122, 'rank':1},{'val': 112, 'rank':1}],
[{'val': 12, 'rank':2},{'val': 122, 'rank':2},{'val': 112, 'rank':2}],
[{'val': 12, 'rank':3},{'val': 122, 'rank':3},{'val': 112, 'rank':3}]
]
how can I retrieve the array that has the 'rank' values set to 3?
const newArray = [{'val': 12, 'rank':3},{'val': 122, 'rank':3},{'val': 112, 'rank':3}];
thanks in advance!
You could use Array.prototype.flat() with Array.prototype.filter() method to get the result.
const oldArray = [
[
{ val: 12, rank: 1 },
{ val: 122, rank: 1 },
{ val: 112, rank: 1 },
],
[
{ val: 12, rank: 2 },
{ val: 122, rank: 2 },
{ val: 112, rank: 2 },
],
[
{ val: 12, rank: 3 },
{ val: 122, rank: 3 },
{ val: 112, rank: 3 },
],
];
const ret = oldArray.flat().filter((x) => x.rank === 3);
console.log(ret);
Assuming all ranks within the inner arrays are the same you could use find() and check the rank of the first element within each array.
const oldArray = [
[{'val': 12, 'rank':1},{'val': 122, 'rank':1},{'val': 112, 'rank':1}],
[{'val': 12, 'rank':2},{'val': 122, 'rank':2},{'val': 112, 'rank':2}],
[{'val': 12, 'rank':3},{'val': 122, 'rank':3},{'val': 112, 'rank':3}],
];
const newArray = oldArray.find(([element]) => element.rank == 3);
console.log(newArray);
This answer uses destructuring to extract the first element of each inner array.
This answer will also throw an error if the inner array can be empty (accessing "rank" of undefined), which can be avoided by using optional chaining. eg. element?.rank == 3

how to get the values of one array of objects key based on values of another array of objects?

data = {
{'uid': 12, 'amount': 100},
{'uid': 23, 'amount': 250}
}
object = {12:{'name':'Paul', 'id':12}, 20:{'name':'Mike', 'id':20}, 41:{'name':'Jack', 'id':41}, 23:{'name':'Luke', 'id':23}}
the output expected is
const result = {{'name':'Paul', 'id': 12, 'amount':100}, {'name':'Luke', 'id': 12, 'amount': 250}}
I tried mapping the uids to get and array of values like
uids = [12, 23]
then
names = uids.map(key => object[key].name);
so that I could use them to map the keys and the names in the other object but couldn't figure it out
I know it is basic javascript but I am new to this
You could simply map the object with the given keys.
var array = [12, 23],
object = { 12: { name: 'Paul', id: 12 }, 20: { name: 'Mike', id: 20 }, 41: { name: 'Jack', id: 41 }, 23: { name: 'Luke', id: 23 } },
result = array.map(key => object[key]);
console.log(result);
var data = {
{'uid': 12, 'amount': 100},
{'uid': 23, 'amount': 250}
};
var object = {12:{'name':'Paul', 'id':12}, 20:{'name':'Mike', 'id':20}, 41:{'name':'Jack', 'id':41}, 23:{'name':'Luke', 'id':23}};
var uids = [12, 23];
mappedValues = uids.map(key => object[key]);
var result = mappedValues.map((item, i) => Object.assign({}, item, data[i]));
console.log(result);
First of all the structure of data is wrong. It should be an array. Then you could do this:
data = [
{'uid': 12, 'amount': 100},
{'uid': 23, 'amount': 250}
];
object = {12:{'name':'Paul', 'id':12}, 20:{'name':'Mike', 'id':20}, 41:{'name':'Jack', 'id':41}, 23:{'name':'Luke', 'id':23}};
for(let key in object){
var match = data.filter(i=>i.uid.toString() === key);
if(match && match.length){
object[key].amount = match[0].amount;
}
}
console.log(object)

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