Convert a one dimensional array into an array of objects with Javascript - javascript

I've flattened an array like this: let playerPool = [...new Set(array.flat(1))];
Which has an output like this: ["Howard Bell", "Matt Blair", "Dave Custer"]
How can I turn this into an array of objects? I want to update the above so the format is like this:
[ {Name: "Howard Bell", Count: "0"}, {Name: "Matt Blair", Count: "0"}, {Name: "Dave Custer", Count: "0"} ]
I was trying to set this up by looping through the playerPool array but I get the following error: TypeError: Cannot set property 'Name' of undefined
let playerPool = [...new Set(array.flat(1))];
let playerObjects = [];
for(let i = 0; i < playerPool.length; i++) {
playerObjects[i].Name = playerPool[i];
playerObjects[i].Count = 0;
}
My goal is to be able to reference each property individually like this playerObjects[0].Count so I can later update the count value.

You forgot to create the object to which you want to assign the properties.
But you can do it more functional-style with map:
let playerPool = ["Howard Bell", "Matt Blair", "Dave Custer"];
let result = playerPool.map(name => ({name, count:0}));
console.log(result);
NB: if possible choose camelCase for your property names. There is a common practice to reserve PascalCase for constructor names ("classes").

You can try something like this,
let array1 = ["Howard Bell", "Matt Blair", "Dave Custer"];
let array2 = [];
array1.forEach(el => {
array2.push({Name: el, count: 0});
});
console.log(array2);

Related

Convert multidimensional array to objects using dynamically generated and predefined array of items I want to set as keys

Are the steps I'm taking to solve this problem correct?
I'm working on turning a data structure of an array of arrays such as
this.arrayofAnimalsAndValues = [
[ "Ant", 1287, 12956],
[ "Lion", 2574, 25826],
[ "Bear", 3861, 38696],
.....
]
into this
this.jsonOfAnimalsAndValues = [
{category: "Ant", value_1: 1287, value_2:12956},
{category: "Lion", value_1: 2574, value_2:25826},
{category: "Bear", value_1: 3861, value_2:38696},
.....
]
where the first item in the array is always assigned to 'category' in the array object and the following items assigned to value_# depending on their order in the array. So the 2nd array item would have key value_1 and so on. For example, for 1 nested array:
[[ "Ant", 5148, 51566]] to =>
[{category: "Ant", value_1: "5148", value_2: 51566}]
I've created a hardcoded way to achieve this however I'm trying to make it dynamic:
'hardcoded' way:
this.variableOfKeys = ["value_1", "value_2", "value_3", ......]
this.jsonOfAnimalsAndValues = this.arrayofAnimalsAndValues(function(x) {
return {
category: x[0],
no1: x[1],
no2: x[2],
.....
};
});
where I just hardcode the keys and their values (values using their index).
My attempt to make it dynamic:
this.variableOfKeys.forEach(element => {
this.jsonOfAnimalsAndValues = this.arrayofAnimalsAndValues.map(function(x) {
for (var i = 0; i<=this.arrayOfValuesToUseAsKeys.length; ++i) {
return {
category: x[0],
element: x[i+1],
};
}
});
});
where my logic is that for each item in
this.variableOfKeys = ["value_1", "value_2", "value_3", ......],
I created this.jsonOfAnimalsAndValues such that the first item (item with the 0th index) in the array this.arrayofAnimalsAndValues is assigned to the key category and the following items (depending on their index) are assigned to the values in this.variableOfKeys in order starting from no1, then no2 etc.
However, I don't think this is written correctly and I keep getting this error:
"TypeError: Cannot read property 'variableOfKeys' of undefined"
Can I ask how it might be written incorrectly and so how I might be able to create this.jsonOfAnimalsAndValues from this.arrayofAnimalsAndValues?
You can map each subarray to an array of entries, then turn it into an object to return with Object.fromEntries:
const arrayofAnimalsAndValues = [
[ "Ant", 1287, 12956],
[ "Lion", 2574, 25826],
[ "Bear", 3861, 38696],
];
const output = arrayofAnimalsAndValues.map(
([category, ...rest]) => Object.fromEntries([
['category', category],
...rest.map((value, i) => ['value_' + (i + 1), value])
])
);
console.log(output);
Given an array of the keys you can map() the main array and use reduce() on each subarray to generate each object
const arr=[["Ant",1287,12956],["Lion",2574,25826],["Bear",3861,38696]],
keys = ['category','value_1','value_2'];
const res = arr.map(e => e.reduce((a,c,i) => (a[keys[i]] = c, a),{}))
console.log(res)
.as-console-wrapper { max-height: 100%!important;top:0}

Javascript combine two array of objects

I would like to combine elements of 2 arrays based on the name. For example:
Array1 = [
{name: "name1", language: "lang1"},
{name: "name2", language: "lang2"},
{name: "name3", language: "lang3"}]
Array2 = [
{name: "name1", subject: "sub1"},
{name: "name2", subject: "sub2"},
{name: "name3", subject: "sub3"}]
I need to generate the following array:
Array3 = [
{language: "lang1", subject: "sub1"},
{language: "lang2", subject: "sub2"},
{language: "lang3", subject: "sub3"}]
The logic I could think of was to write an explicit for loop to compare every element of first array with every element of second array and check if name matches as shown below.
let Array3 = []
for(let i=0;i<Array1.length;i++)
{
let elem = Array1[i];
for(let j=0;j<Array2.length;j++)
{
if(Array2[j].name===elem.name)
{
Array3.append({language: elem.language, subject: Array2[j].subject})
break;
}
}
}
However, my actual dataset is quite large and this seems inefficient. How can this can be achieved in a more efficient manner (like using higher order functions or something)?
Using a Map for O(1) lookup of one of the arrays using name as key lets you iterate each array only once.
const Array1=[{name:"name1",language:"lang1"},{name:"name2",language:"lang2"},{name:"name3",language:"lang3"}],Array2=[{name:"name1",subject:"sub1"},{name:"name2",subject:"sub2"},{name:"name3",subject:"sub3"}];
const a1Map = new Map(Array1.map(({name, ...r})=> [name, {...r}]));
const res = Array2.map(({name, ...r}) => ({...r, ...a1Map.get(name)}))
console.log(res)
You need to iterate over the two arrays and group the generated object in a map having the name as the key:
let Array1 = [
{name: "name1", language: "lang1"},
{name: "name2", language: "lang2"},
{name: "name3", language: "lang3"}
];
let Array2 = [
{name: "name1", subject: "sub1"},
{name: "name2", subject: "sub2"},
{name: "name3", subject: "sub3"}
];
let map = new Map();
Array1.forEach(e => map.set(e.name, {language: e.language}));
Array2.forEach(e => {
if(map.has(e.name))
map.set(e.name, {...map.get(e.name), subject: e.subject});
});
let Array3 = [...map.values()].filter(e => e.language && e.subject);
console.log(Array3);
Yes you are thinking in right order , you need to use the sort algorithm logics , I will say nested for loops will be just as good. With larger dataset , since you need to extract the values from two different array you can use the nested for loops.
for(int i=0;i>array1.length();i++){
This can be use for first array
Define String x=",";
For second
for(int j=0;j>array2.length();j++)
{
Check if ( (","+j+",").contains(x)) then break;
If array1 name found in array 2, store array3 as you want
Also Store value of j in x
Like x=x +j+",";
}}
This way your nested for loop will skip the comparison code.
Above algo is raw but will reduce the complexity a significant bit.

How to groupBy object using lodash?

I am using ReactJS. I have an object which looks like this:
{
autumn=firstContactPersonName: "John",
autumn=firstContactPersonPhone: "46442644",
autumn=secondContactPersonName: "Jhonny",
autumn=secondContactPersonPhone: "46442644",
christmas=firstContactPersonName: "Tommy",
christmas=firstContactPersonPhone: "46442644",
christmas=secondContactPersonPhone: "Thomas",
winter=firstContactPersonPhone: "46442644",
winter=firstContactPersonName: "Peter",
winter=secondContactPersonName: "Tom",
winter=secondContactPersonPhone: "44664455"
}
How can I group them based on autumn, christmas, winter. So one object with autumn have the autumn fields, the second one christmas have the christmas field, and the third one winter have the winter fields?
And so on. All fields will have a segment name before =, so I can easily see what kind of segment they belong to.
This is achievable with pure JS, no need for lodash (which I'm not familiar with).
This function takes every property of your input object, splits the key around the equals sign for the season part (prefix) and rest (appendix). Afterwards it looks for an object in the output array with the same season and adds the properties to it. If there is no object with specified season, it creates a new one.
function processData(inputObj) {
var data = [];
for (var key in inputObj) {
var prefix = key.split("=")[0];
var appendix = key.split("=")[1];
var dataObject = data.find(o => o.season == prefix);
if (!dataObject) {
dataObject = {season: prefix};
data.push(dataObject);
}
dataObject[appendix] = inputObj[key];
}
return { data };
}
produces this output:
{
"data": [
{
"season": "autumn",
"firstContactPersonName": "John",
"firstContactPersonPhone": "46442644",
"secondContactPersonName": "Jhonny",
"secondContactPersonPhone": "46442644"
},
{
"season": "christmas",
"firstContactPersonName": "Tommy",
"firstContactPersonPhone": "46442644",
"secondContactPersonPhone": "Thomas"
},
{
"season": "winter",
"firstContactPersonPhone": "46442644",
"firstContactPersonName": "Peter",
"secondContactPersonName": "Tom",
"secondContactPersonPhone": "44664455"
}
]
}
You can produce your groups by looping over the keys in the object. Split the key on = and capture the results. The first element should be the group, the second the property to access within this group.
Create a new object if a group doesn't yet exist. Then set the property within the group equal to the value of the original object.
const input = {
"autumn=firstContactPersonName": "John",
"autumn=firstContactPersonPhone": "46442644",
"autumn=secondContactPersonName": "Jhonny",
"autumn=secondContactPersonPhone": "46442644",
"christmas=firstContactPersonName": "Tommy",
"christmas=firstContactPersonPhone": "46442644",
"christmas=secondContactPersonPhone": "Thomas",
"winter=firstContactPersonPhone": "46442644",
"winter=firstContactPersonName": "Peter",
"winter=secondContactPersonName": "Tom",
"winter=secondContactPersonPhone": "44664455"
};
const output = {};
for (const key in input) {
const [season, property] = key.split("=", 2);
if (!output[season]) output[season] = {};
output[season][property] = input[key];
}
console.log(output);
I find my explanation a bit confusion, but I hope that combined with the code snippet you understand what I'm saying.
Use Object.entries() to generate an array of [key, value] pairs, and iterate with Array.reduce(). For each pair, split the key by = to get the group key, and the value key, create the group's object if none exists, and assign the value to the object.
const data = {"autumn=firstContactPersonName":"John","autumn=firstContactPersonPhone":"46442644","autumn=secondContactPersonName":"Jhonny","autumn=secondContactPersonPhone":"46442644","christmas=firstContactPersonName":"Tommy","christmas=firstContactPersonPhone":"46442644","christmas=secondContactPersonPhone":"Thomas","winter=firstContactPersonPhone":"46442644","winter=firstContactPersonName":"Peter","winter=secondContactPersonName":"Tom","winter=secondContactPersonPhone":"44664455"}
const result = Object.entries(data)
.reduce((r, [k, v]) => {
const [gKey, key] = k.split('=') // get the key
r[gKey] = r[gKey] || {} // generate the object if it doesn't exist
r[gKey][key] = v // assign the value to the object
return r
}, {})
console.log(result);

JS arrays: how to compare two and create third

It's my first post here :-)
Please, Can you a advice on this:
I have an object and an Array:
activeItems = {
itemId: ["itemid1", "itemid2", "itemid3", "itemid4", "itemid5", "itemid6", "itemid7", "itemid8", "itemid9", "itemid10"],
price: ["10.50", "22.10", "13.40", "11", "1100", "500", "100", "400", "500", "20"]
};
selectItems = ["itemid3", "itemid8", "itemid9"];
In the activeItems object price[0] represents the price for itemId[0].
All the prices are in correct order to represent prices for all item ids.
Now, I would like to create a new object with prices for the selecteItems array.
It should look like this:
newObject = {
itemId: ["itemid3","itemid8","itemid9"],
price: ["13.40", "400", "500"]
};
Basically, I'm looking for a formula that creates new object for selectedItems out of activeItems and adds prices arrays for them.
Thank you in advance!
Use a forEach loop and get the index of items from activeItems.itemId which can be used to get the corresponding price value from activeItems.price.
var activeItems = {
itemId: ["itemid1", "itemid2", "itemid3", "itemid4", "itemid5", "itemid6", "itemid7", "itemid8", "itemid9", "itemid10"],
price: ["10.50","22.10","13.40","11","1100","500","100","400","500","20"]
};
var selectItems = ["itemid3","itemid8","itemid9"];
var itemId = [];
var price = [];
selectItems.forEach(function(item){
var index = activeItems.itemId.indexOf(item);
itemId.push(item);
price.push(activeItems.price[index]);
});
var newObject = {
itemId: itemId,
price : price
};
console.log(newObject);
Maybe this is what you need: Key value arrays:
var myArray = {"itemid3": "13.40", "itemid8": "400", "itemid9": "500"};
And you add new items like this:
myArray = [];
myArray.itemid15 = "300";
Use the array reduce function
var activeItems = {
itemId: ["itemid1", "itemid2", "itemid3", "itemid4", "itemid5", "itemid6", "itemid7", "itemid8", "itemid9", "itemid10"],
price: ["10.50", "22.10", "13.40", "11", "1100", "500", "100", "400", "500", "20"]
};
var selectItems = ["itemid3", "itemid8", "itemid9"];
var newObject = selectItems.reduce(function(acc, curr, index) {
// acc is the object passes as an argument
// curr is current element
// in this case curr will be "itemid3", "itemid8", "itemid9" ..so on
acc.itemId.push(curr);
// in next step get the index of the itemId3 etc from the original array
// use this index to get the value from activeItems .price
acc.price.push(activeItems.price[activeItems.itemId.indexOf(curr)])
return acc;
}, {
itemId: [],
price: []
});
console.log(newObject)

acessing new object from Object.keys and forEach method javascript

I'm trying to create a new object (newobj) with new keys and props from a poorly structured existing array of object (arrays?) ex.
[{"product":["1009", "name", "price", "image", "description"]},
{"product":["1004", "name2", "price2", "image2", "description2"]}]
I'm getting result I want but newobj does not update outside of the scope of the forEach method (more than 1 result). My question is what am I not getting ? Is forEach incorrect method with this type obj?
var newobj = {};
Object.keys(oldobj).forEach(function(prop) {
newobj["id"] = Number(oldobj[prop]["product"][0]),
newobj["name"] = oldobj[prop]["product"][1],
newobj["price"] = Number(oldobj[prop]["product"][3]),
newobj["image"] = "url" + oldobj[prop]["product"][0] + ".jpg",
newobj["description"] = oldobj[prop]["product"][2];
// this works
// console.log(JSON.stringify(newobj));
});
// this only updated with one
app.locals.newobj = newobj;
I've also tried mapping (w/ underscore) but I have the same result, I can't access outside scope.
_.each(mappedobj, function(prop) {
_.each(prop["product"][0], function(vals){
newobj["id"] = Number(prop["product"][0]);
console.log(JSON.stringify(newobj));
});
});
If you want all the values from the old object, you need to make newobj an array of objects. You can use .map() to do this transformation.
Object and array destructuring is a convenient way to avoid all those hard-coded indexes. And by naming the parameter variables properly, you can use object literal shorthand to create the resulting objects more easily.
var oldobj = [{
"product": ["1009", "name", "price", "image", "description"]
},
{
"product": ["1004", "name2", "price2", "image2", "description2"]
}
];
var newobj = oldobj.map(({product: [id, name, price, url, description]}) =>
({id: Number(id), name, price: Number(price), url: `url${url}.jpg`, description})
);
console.log(newobj);
Try this
let newObject = _.map(oldObject, (item) => {
return {
id: item.product[0],
name: item.product[1],
price: item.product[2],
image: item.product[3],
description: item.product[4]
};
});
If you want to convert an array of poorly structured object to an array of well structured ones, you can use Array.prototype.map from VanillaJS:
const data = [
{"product": ["1009", "name", "120", "image", "description"]},
{"product": ["1004", "name2", "250", "image2", "description2"]},
{"product": ["1012", "name3", "85", "image3", "description3"]}
];
const products = data.map(({ product }) => {
const [id, name, price, image, description] = product;
return {
id: Number(id),
name,
price: Number(price),
image: `url${image}.jpg`,
description
};
});
console.log(products);

Categories