How to make properties in list into values? - javascript

Is there any way to convert a list of objects into a new list where the properties are now values. I have tried to use Object.keys() and Object.values() to make two separate lists and then trying to combine them, without much success.
Example:
I want to turn:
[{ip: 123, name: "bob"}]
into:
[{property: "ip", value: 123}, {property: "name", value: "bob"}]
How do I solve this problem?

I would simply do a for loop, go through the array and then push these new objects in a new array.
The following code should solve your issue:
const array1 = [{ ip: 123, name: 'bob' }];
let newArray;
for (let i = 0; i < array1.length; i++) {
newArray.push({
property: 'ip',
value: array1[i].value
});
newArray.push({
property: 'name',
value: array1[i].name
});
}

You could use upcoming Array#flatMap and take the entries of the object.
var data = [{ ip: 123, name: "bob" }],
result = data.flatMap(o => Object.entries(o).map(([property, value]) => ({ property, value })));
console.log(result);
Traditional approach with Array#reduce.
var data = [{ ip: 123, name: "bob" }],
result = data.reduce((r, o) => [
...r,
...Object.entries(o).map(([property, value]) => ({ property, value }))
], []);
console.log(result);

Related

How to make {value,array[i]} object pairs in javascript

I'm receiving from backend side object which is formulated like:
[
{value: 'FIRST', AvailableValues[{code: "one"},{code: "two"}]},
{value: 'SECOND', AvailableValues[{code: "one"},{code: "two"}]
]
My question is how to map through this object to create pairs like
[{value: "FIRST", code:"one"},
{value: "FIRST", code:"two"},
{value: "SECOND", code:"one"},
{value: "SECOND", code:"two"}]
Thanks
I tried combination of javascript predefined methods like double map, keyed search and so on, but it resulted with errors
use reduce function
Also, your initial data should be an array because if it's a object, then it should contains key with values
const list = [
{value: 'FIRST', AvailableValues:[{code: "one"},{code: "two"}]},
{value: 'SECOND', AvailableValues:[{code: "one"},{code: "two"}]}
]
const result = list.reduce((acc,item) => {
const res = item.AvailableValues.map(i => ({value: item.value, code: i.code}))
return [...acc,...res]
}, [])
console.log(result)
Try something like this, Assuming that you receiving array of object from backend
let result = [];
yourObject.forEach((x)=>{
x.AvailableValues.map((innerItem)=>{
result.push({value:x.value, code : innerItem.code})
});
})
console.log(result)
The other answers here gets the job done. For completion here is an approach using flatMap combined with an inner map
const data =[
{value: 'FIRST', AvailableValues:[{code: "one"},{code: "two"}]},
{value: 'SECOND', AvailableValues:[{code: "one"},{code: "two"}]}
]
const res = data.flatMap(({value,AvailableValues}) => AvailableValues.map(({code}) => ({value,code})))
console.log(res)
var response = [{
value: 'FIRST', AvailableValues: [{ code: "one" }, { code: "two" }]},{
value: 'SECOND', AvailableValues: [{ code: "one" }, { code: "two" }]}
];
var output = [];
response.forEach(function(o) {
o.AvailableValues.forEach(function(oo) {
var t = {
value: o.value,
code: oo.code
};
output.push(t);
})
});
console.log(output);

Array.from for array-of-objects. How to uniquely id each object?

I need to create an array that contains Nx duplicates of an input array-of-objects, and assign a unique ID to each individual object in the output array.
I know I can do the initial duplication, like so...
let input = [ { type: 123, name: 'apples'} , { type: 456, name: 'pears'} ]
let output = [ ...Array.from( {length: 3}, () => (input)) ].flat(1)
to get me..
[ { id: 123, name: 'apples'} , { id: 456, name: 'pears'}, { id: 123, name: 'apples'} , { id: 456, name: 'pears'}, { id: 123, name: 'apples'} , { id: 456, name: 'pears'} ]
but I don't know how, as part of that Array.from step, to add a unique ID to each object?
(Since each input object has it's own type, which is unique, I'd like to just combine that with it's set number, e.g. for the 1st & 3rd elements it's uniqueID would be 123-0, 123-1)
I know how to acheive it with for loops...
let output = []
for (let i=0; i<N; i++) {
for (let j = 0; j < input.length; j++) {
let newObject = { ...input[j] }
newObject.id = newObject.field1.ID+'-'+j
output.push(newObject)
}
}
but I'd like to learn how I could achieve the same whilst using Array.from, or some other similar function?
The callback argument of Array.from() is passed a collection element (which is undefined in your example) and an index. You can then map() over input and combine the type of each element with the current "set" index
let input = [ { type: 123, name: 'apples'} , { type: 456, name: 'pears'} ];
let output = Array.from(
{ length: 3 },
(_, i) => input.map((item) => ({ id: `${item.type}-${i}`, ...item }))
).flat(1);
console.log(output);
You can use the Array.map function
let output = [ ...Array.from( {length: 3}, () => (input)) ].flat(1).map((a, idx) => a = {...a, id: a.name.ID + '-' + idx})
You can use the callback function of the Array.from method to update the type. Check it out-
const input = [{type: 123, name: 'apples'} , {type: 456, name: 'pears'}];
const output = Array.from( {length: 3}, (_, i) => {
return input.map(item => ({...item, id: `${item.type}-${i}`}));
}).flat();
console.log(output);
.as-console-wrapper{min-height: 100%!important; top: 0}
Alternatively: a somewhat more generic multiplier function
const initial = [{
type: 123,
name: 'apples'
}, {
type: 456,
name: 'pears'
}];
const multiply = (initialArray, n = 3, serialKey = `type`) =>
[].concat(...[...Array(n)]
.map( (_, i) =>
initialArray.map( v => ({ ...v, [serialKey]: `${v[serialKey]}-${i}` }) ) )
);
console.log(multiply(initial, 4));

Transforming Javascript Array

I'm not sure what would be the best way to approach transforming this JS Array.
I have an array with a structure like (could contain more than 1 element):
let arr1 = [{amount: '10', quantity: 2, id: '123'}, {....}]
but I need to take that and transform that into an array structured like
let arr2 = [{value: '10'}, {value: '10'}]
Essentially adding new objects into the array based on the quantity in array 1.
I was thinking basic for loop but it seems to be getting a bit messy. Is there a simple way in JS to do this? Either with some sort of built in function etc?
You can easily get the result using flatMap.
First, you can create a temp array with the number of elements as quantity then map over the temp array to get the object with property amount in it.
let arr1 = [
{ amount: "10", quantity: 2, id: "123" },
{ amount: "30", quantity: 5, id: "123" },
];
const result = arr1.flatMap((obj) => {
const { amount, quantity } = obj;
return Array(quantity)
.fill(0)
.map((x) => ({ amount }));
});
console.log(result);
You can also make the above snippet succinct
const result = arr1.flatMap(({ quantity, amount }) => Array(quantity).fill(0).map((x) => ({ amount })));
let arr1 = [
{ amount: "10", quantity: 2, id: "123" },
{ amount: "30", quantity: 5, id: "123" },
];
const result = arr1.flatMap(({ quantity, amount }) =>
Array(quantity)
.fill(0)
.map((x) => ({ amount }))
);
console.log(result);
I was thinking basic for loop but it seems to be getting a bit messy
You just need a simple for and a while loop:
const input = [{amount: '10', quantity: 2, id: '123'}],
output = []
for (let { amount, quantity } of input)
while (quantity--)
output.push({ value: amount })
console.log(output)
You could create o.quantity number of objects using Array.from(). Use flatMap to get a flat array for each item in the input array
const output = input.flatMap(o =>
Array.from({ length: o.quantity }, _ => ({ value: o.amount }) )
)
You could also do it using reduce, with a manual for loop to append the correct number of entries.
let arr1 = [{amount: '10', quantity: 2, id: '123'}];
const result = arr1.reduce((accum, v) => {
for (let i = 0; i < v.quantity; i++) {
accum.push({value: v.amount});
}
return accum;
} , []);
This might have a slight performance improvement over flatMap, as it does not create any temporaries.

What is the most efficient way to convert an array of objects to an object

Trying to convert an array of objects to a single object and the array I have is similar to the following;
const array = [{id: '1', name: 'First'}, {id: '2', name: 'Second'}];
Expected output:
{'first': 1, 'second': 2}
Additionally, I want to change the casing of all values to lower case. Can assume that there are no spaces in between for the values for names. And all the ids are numbers.
Performance-wise, is there a better approach than this?
const array = [{id: '1', name: 'First'}, {id: '2', name: 'Second'}];
console.log(array);
const result = array.reduce((accumulator, value) => {return {...accumulator, [value.name.toLowerCase()]: Number(value.id)}}, {});
console.log(result);
A simple for ... of (or similar) will likely be most performant as it has no overhead of function calls. For example:
const array = [
{id: '1', name: 'First'},
{id: '2', name: 'Second'}
];
let result = {};
for (o of array) {
result[o.name.toLowerCase()] = parseInt(o.id);
}
console.log(result);
I think using a standard loop (for or while) would be the most efficient performance wise since it doesn't come with any additional stuff like map,reduce,sort do.
You could create entries and generate an object from it.
const
array = [{ id: '1', name: 'First' }, { id: '2', name: 'Second' }],
object = Object.fromEntries(array.map(({ id, name }) => [name.toLowerCase(), +id]));
console.log(object);

How can I return the property values of a nested JavaScript array nested in an object from JSON?

Given a JS array containing many objects which all contain arrays:
var data = [
{id: 1, name: "Fred", pages:[{url:"www.abc.com", title: "abc"}]},
{id: 2, name: "Wilma", pages:[{url:"www.123.com", title: "123"}]},
{id: 3, name: "Pebbles", pages:[{url:"www.xyz.com", title: "xyz"}]}
];
How do I efficiently extract the inner most array (pages) values into an array?
var dataArray = [
{url: "www.abc.com", title: "abc"},
{url: "www.123.com", title: "123"},
{url: "www.xyz.com", title: "xyz"}
]
The easiest way to do this is to use Array#map like so:
var dataArray = data.map(function(o){return o.pages});
If pages is an array of objects (not a single object), this will result in an array of arrays, which you will need to flatten out for example using Array#reduce:
dataArray = dataArray.reduce(function(a,b){return a.concat(b)}, []);
You are looking for a flatMap
var data = [
{id: 1, name: "Fred", pages:[{url:"www.abc.com", title: "abc"}]},
{id: 2, name: "Wilma", pages:[{url:"www.123.com", title: "123"}]},
{id: 3, name: "Pebbles", pages:[{url:"www.xyz.com", title: "xyz"}]}
];
const concat = (xs, ys) => xs.concat(ys);
const prop = x => y => y[x];
const flatMap = (f, xs) => xs.map(f).reduce(concat, []);
console.log(
flatMap(prop('pages'), data)
);
If by "efficiently" you actually mean "concisely", then
[].concat(...data.map(elt => elt.pages))
The data.map will result in an array of pages arrays. The [].concat(... then passes all the pages arrays as parameters to concat, which will combine all of their elements into a single array.
If you are programming in ES5, the equivalent would be
Array.prototype.concat.apply([], data.map(function(elt) { return elt.pages; }))
Here's a working example on how to achieve what you want:
var data = [
{id: 1, name: "Fred", pages:[{url:"www.abc.com", title: "abc"}, {url:"www.google.com", title: "Google"}]},
{id: 2, name: "Wilma", pages:[{url:"www.123.com", title: "123"}]},
{id: 3, name: "Pebbles", pages:[{url:"www.xyz.com", title: "xyz"}]}
];
var arr = Array();
var arr2 = Array();
// You can either iterate it like this:
for (var i = 0; i < data.length; i++) {
// If you only want the first page in your result, do:
// arr.push(data[i].pages[0]);
// If you want all pages in your result, you can iterate the pages too:
for (var a = 0; a < data[i].pages.length; a++) {
arr.push(data[i].pages[a]);
}
}
// Or use the array map method as suggested dtkaias
// (careful: will only work on arrays, not objects!)
//arr2 = data.map(function (o) { return o.pages[0]; });
// Or, for all pages in the array:
arr2 = [].concat(...data.map(function (o) { return o.pages; }));
console.log(arr);
console.log(arr2);
// Returns 2x [Object { url="www.abc.com", title="abc"}, Object { url="www.123.com", title="123"}, Object { url="www.xyz.com", title="xyz"}]
use array map() & reduce() method :
var data = [
{id: 1, name: "Fred", pages:[{url:"www.abc.com", title: "abc"}]},
{id: 2, name: "Wilma", pages:[{url:"www.123.com", title: "123"}]},
{id: 3, name: "Pebbles", pages:[{url:"www.xyz.com", title: "xyz"}]}
];
var dataArray = data.map(function(item) {
return item.pages;
});
dataArray = dataArray.reduce(function(a,b) {
return a.concat(b);
}, []);
console.log(dataArray);

Categories