How to convert array to object in js? - javascript

I have got list of arrays .
let arr = ["one","two"]
My trying code is:
arr.map(item=>{
item
})
I want to convert array of sub-array
[
{
"one": [{
value: "one"
},
]
},
{
"two": [{
value: "two"
},
]
},
]

You can try with using Object.values().
const arr = ["one", "two"];
const result = Object.values(arr).map(e => {
return {
[e]: [{value: e}]
}
});
console.log(result);

you can also do it like this
let arr = ["one","two"]
arr.map(orgValue => {
[orgValue]: [
{
value: orgValue
}
]
};
);

A simple forEach loop would help
let arr = ["one", "two"];
var res = [];
arr.forEach(val => {
res.push({
[val]: [
{
value: val
}
]
});
});
console.log(res);

Related

how to create 2 arrays by running once on an array containing objects with the arrays matching the fields?

for example - lets say I have the array -
const array = [{name: "first", val: 1}, {name: "second", val: 2}]
I want to run once on that array and at the end of that run to have two arrays -
const arrayOne = ["first", "second"];
const arrayTwo = [1,2];
to get the first one is easy, but getting both at once?
I remember there was a way to do it but couldn't find it..
I'd appreciate any help!
Any looping logic will help
Array.reduce implementation will be like below
const array = [{ name: "first", val: 1 }, { name: "second", val: 2 }];
const [arrayOne, arrayTwo] = array.reduce((acc, curr) => {
const { name, val } = curr;
acc[0].push(name);
acc[1].push(val);
return acc;
}, [[], []]);
console.log(arrayOne, arrayTwo);
The function extractArrays is general-purpose and can be used in other cases as well.
function extractArrays(arr) {
const result = {};
for (obj of arr) {
for (key in obj) {
result[key] = (result[key] || []).concat([obj[key]]);
}
}
return result;
}
const array = [{name: "first", val: 1}, {name: "second", val: 2}];
const result = extractArrays(array);
const arrayOne = result.name;
const arrayTwo = result.val;
console.log(`arrayOne=${arrayOne}`);
console.log(`arrayTwo=${arrayTwo}`);
You can use Array.reduce to achieve this:
const array = [{name: "first", val: 1}, {name: "second", val: 2}]
const result = array.reduce((res, item) => {
res[0].push(item.name)
res[1].push(item.val)
return res
}, [[], []])
console.log(result)
thanks everyone!
but I think that the easiest, most readable code would be something like -
const itemArray = [], valArray = [];
data.map(({name, val})=> {
if(name) nameArray.push(name);
if(val) valArray.push(val);
})
because basically in 4 lines of code it's finished
thanks again everyone!
const array = [{name: "first", val: 1}, {name: "second", val: 2}]
const keys = [];
const values = [];
array.forEach(item=>{
keys.push(item.name);
values.push(item.val);
})
console.log(keys, values)
Use the Array.map function:
const array = [ { name: 'first', val: 1 }, { name: 'second', val: 2 } ]
let names = array.map(item => item.name)
let vals = array.map(item => item.val)
console.log(names)
console.log(vals)
The map function calls a callback function you provide on each element and constructs a new array from the results of that function.
If you are not familiar with arrow functions like:
item => item.name
... it is a short form for:
function (item) {
return item.name
}
You could even do it in one line:
let [ names, vals ] = [ array.map(item => item.name), array.map(item => item.val) ]

How to display the data of array inside the array in angular

data = [
{
rows: [
{ name: 'a'}
]
},
{
rows: [
{ name: 'b'}
]
}
{
rows: []
}
]
what I'm trying to do here is to get the rows data. which is like this.
expected output:
data = [
{
name: 'a'
},
{
name: 'b'
}
];
where it will remove the empty array and it will merge on it.
Approach 1:
You can use reduce on your array as below -
var data = [
{
rows: [
{ name: 'a'}
]
},
{
rows: [
{ name: 'b'}
]
},
{
rows: []
}
]
var reducedSet = [];
data.reduce((accumulator, currentValue, currentIndex) => {
var currentRows = currentValue.rows;
var rowLength = currentRows && currentRows.length
if (rowLength) {
for (i = 0; i < rowLength; i++) {
accumulator.push(currentRows[i]);
}
return accumulator;
}
}, reducedSet);
console.log(reducedSet);
Approach 2:
Alternatively, you can also do it as below -
var data = [
{
rows: [
{ name: 'a'}
]
},
{
rows: [
{ name: 'b'}
]
},
{
rows: []
}
];
var result = data.filter(f => f.rows && f.rows.length && f.rows.length > 0).map((currentValue) => {
return currentValue.rows;
}).flat();
console.log(result);
Above code first filters out the empty rows and then maps the out the data and finally flattens the result.
data = [
{
rows: [
{ name: 'a'},
]
},
{
rows: [
{ name: 'b'},
]
},
{
rows: []
}
]
let mappedData = data.map(obj => {
return obj.rows.map(obj2 => {
return {
name: obj2.name
}
})
})
mappedData = mappedData.flat()
console.log(mappedData)
Try something like that, I guess that's what you want from what I've seen.
This might help. The solution provided takes into account that there might be multiple name inside a single rows.
let data = [] // YOUR OBJECT IN THE QUESTION
let data2: any = []
data.forEach(el => {
if(el.rows.length > 0) {
data2 = [...data2, ...el.rows];
}
})
console.log('data2', data2);
If you want to one-line it with modern Javascript, this is the way.
const transform = (inData) => inData.reduce((outData, { rows }) => outData.concat(rows), []);
Basically, create a new array, then for each entry in inData extract the content of the rows property and add it to the array.
data.filter(x => {
x.rows !== [];
});
You could filter the array.

JavaScript nested map()

I have an array:
const array = [
{name: "abc", numbers:[1,2]},
{name: "def", numbers:[3,4]}
];
I want to use .map() to return a new array like:
[
{name:"abc", number:1},
{name:"abc", number:2},
{name:"def", number:3},
{name:"def", number:4}
]
What should I do?
It would be more performant to use forEach instead of map.
As #MohammadUsman's nice answer shows, the output of map has to be flattened before you can get the result you want. With forEach (which returns nothing), you can just append to the output array directly:
const data = [
{ name: "abc", numbers: [1,2] },
{ name: "def", numbers: [3,4] }
];
var result = [];
data.forEach(
({ numbers, ...rest }) => numbers.forEach(
n => result.push(Object.assign({number: n}, rest )))
);
console.log(result);
You can iterate over input array using .map() and use Object.assign() to generate new object and finally flat the array using .flat() to get the desired output.
const data = [
{ name: "abc", numbers: [1,2] },
{ name: "def", numbers: [3,4] }
];
const result = data.map(
({ numbers, ...rest }) => numbers.map(n => Object.assign({number: n}, rest ))
).flat();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could take directly Array#flatMap with an inner mapping of new objects and get an array of objects.
const
array = [{ name: "abc", numbers:[1, 2] }, { name: "def", numbers:[3, 4] }],
result = array.flatMap(({ name, numbers }) => numbers.map(number => ({ name, number })));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use .reduce if flatmap not available. It is faster in your cases. Iteration will be only one time for each element.
const array = [
{ name: "abc", numbers: [1, 2] },
{ name: "def", numbers: [3, 4] },
];
const results = array.reduce((r, item) => {
r = r.concat(item.numbers.map((number) => ({ name: item.name, number })));
return r;
}, []);
console.log(results)
Here is a simple solution if you are up for using jquery...
const array = [
{name: "abc", numbers:[1,2]},
{name: "def", numbers:[3,4]}
];
var newArray = [];
$.each(array, function(k,v){
var strName = v.name;
$.each(v.numbers, function(key,value){
newArray.push({name: strName, number: value});
});
});
console.log(newArray);

Group array of objects based on array-type key

Having input like the below:
[
{
gameId: id_0,
groups: [1]
},
{
gameId: id_1,
groups: [2]
},
{
gameId: id_2,
groups: [1, 2]
},
{
gameId: id_3,
groups: [3]
}
]
I would like my reduce to result in an array of objects like:
[
{
group: 1,
data: [
id_0, id_2 // gameId
]
},
{
group: 2,
data: [
id_1, id_2
]
},
{
group: 3,
data: [
id_3
]
}
]
I was able to partially solve this by utilising array indexes.
The code I have currently is:
groupByArr = parameter => data => data.reduce((acc, curr) => {
curr[parameter].forEach(key => {
if (acc[key]) {
acc[key].push(curr)
} else {
acc[key] = [curr]
}
})
return acc
}, [])
which produces an array of arrays where main array index is the group id:
[
empty,
1: [
id_0, id_2
],
2: [
id_1, id_2
],
3: [
id_3
]
]
You can use Array.prototype.reduce() combined with Array.prototype.forEach() and Array.prototype.push() to return an Object and finally get the values with Object.values()
Code:
const data = [{gameId: 'id_0',groups: [1]},{gameId: 'id_1',groups: [2]},{gameId: 'id_2',groups: [1, 2]},{gameId: 'id_3',groups: [3]}]
const result = Object.values(data.reduce((acc, {gameId, groups}) => {
groups.forEach(group => {
acc[group] = acc[group] || { group, data: [] }
acc[group].data.push(gameId)
})
return acc
}, {}))
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Let arr be the variable containing data in following format:
[
empty,
1: [
id_0, id_2
],
2: [
id_1, id_2
],
3: [
id_3
]
]
Then following code might do:-
for(let i=1;i<arr.length;i++){
arr[i-1] = {group:i,data:arr[i]};
}
arr[arr.length-1] = undefined; // To Prevent Unnecessary Errors
delete arr[arr.length-1]; // To Prevent Unnecessary Errors
arr.length -= -1;
Now arr will be in following format:-
[
{
group: 1,
data: [
id_0, id_2
]
},
{
group: 2,
data: [
id_1, id_2
]
},
{
group: 3,
data: [
id_3
]
}
]
Hope it helps. Tell me if I Misunderstood your question.
Use an object as acc, then add objects to it:
if (acc[key]) {
acc[key].data.push(curr)
} else {
acc[key] = { group: key, data: [curr] };
}
And finally, turn the returned object into an array:
const result = Object.values(hash);
Try this
const data = [
{gameId: 'id_0',groups: [1]},
{gameId: 'id_1',groups: [2]},
{gameId: 'id_2',groups: [1, 2]},
{gameId: 'id_3',groups: [3]}
]
const single_id = data.filter(i => i.groups.length === 1)
const multiple_ids = data.filter(i => i.groups.length > 1)
let res = [];
single_id.map(i => {
let data = {group: i.groups[0], data: [i.gameId]}
multiple_ids.forEach(o => o.groups.includes(i.groups[0]) && (data.data.push(o.gameId)))
res.push(data)
})
console.log(res)
`let b = [
{
gameId: "id_0",
groups: [1]
},
{
gameId: "id_1",
groups: [2]
},
{
gameId: "id_2",
groups: [1, 2]
},
{
gameId: "id_3",
groups: [3]
}
];
let d = new Map(); ;
b.forEach(function(a){
a.groups.forEach(function(a1){
if(d.get(a1)){
d.get(a1).push(a.gameId);
}else{
d.set(a1, [a.gameId]);
}
});
});`
You should try this one. Using reduce in grouped scenarios is the best thing JavaScript provides us
let arr = [
{
gameId: "id_0",
groups: [1]
},
{
gameId: "id_1",
groups: [2]
},
{
gameId: "id_2",
groups: [1, 2]
},
{
gameId: "id_3",
groups: [3]
}
];
const grouped = arr.reduce((acc, current) => {
for(let x of current.groups){
if(!acc[x]) {
acc[x] = {group: x, data:[current.gameId]}
} else {
acc[x].data.push(current.gameId)
}
}
return acc
},{});
console.log(Object.values(grouped))

Best way to compare an array of strings to an array objects with string properties?

I have an array of object, within those objects is a name property.
const objArr = [ { name: "Avram" }, { name: "Andy" } ];
I’m collecting an array of strings from an outside source containing names.
const strArr = [ "Avram", "Andy", "Brandon" ];
If strArr contains a string that does not exist as a property name on an object in objArr, I need to create a new object and push it to objArr.
For example: objArr.push( { name: "Brandon" } );
Obviously, I can use nested loops, but I’d like to avoid that if possible. What is the best way to do this programmatically?
like this
const objArr = [ { name: "Avram" }, { name: "Andy" } ];
const strArr = [ "Avram", "Andy", "Brandon" ];
const names= objArr.map(x => x.name);
strArr.forEach(str => {
if (! names.includes(str) ) {
objArr.push({name: str});
}
});
console.log(objArr);
function fillMissing(arr, names) {
names.forEach(name => { // for each name in names
if(arr.every(obj => obj.name !== name)) { // if every object obj in the array arr has a name diferent than this name (this name doesn't exist in arr)
arr.push({name}); // then add an object with that name to arr
}
});
}
const objArr = [ { name: "Avram" }, { name: "Andy" } ];
const strArr = [ "Avram", "Andy", "Brandon" ];
fillMissing(objArr, strArr);
console.log(objArr);
Map objArr to same structure as strArr. Then concat the 2 arrays. Run it through a Set to remove duplicates, then remap to correct array of object
const objArr = [ { name: "Avram" }, { name: "Andy" }, { name: "John"} ];
const strArr = [ "Avram", "Andy", "Brandon" ];
const res = Array.from(new Set(objArr.map(i=>i.name).concat(strArr))).map(i=>({name:i}))
console.log(res);
const objArr = [ { name: "Avram" }, { name: "Andy" } ];
const strArr = [ "Avram", "Andy", "Brandon" ];
const objNamesArr = objArr.map((obj) => obj.name)
strArr.forEach((ele) => objNamesArr.indexOf(ele) == -1 && objArr.push({name:ele}))
console.log('objArr', objArr);
console.log('strArr', strArr);

Categories