JS : Convert Array of Strings to Array of Objects - javascript

i have this array of strings :
let myArray : ["AA","BB" , "CC" ...]
I want to convert it to an array of objects:
myArray = [{"id":1 , "value": "AAA"},{"id":2 , "value": "BBB"},{"id":3 , "value": "CCC"}...]
I ve trie with "let for":
for (let obj of ListObj) {
let resObj = {};
resObj ['value'] = obj ;
equipment = resObj ;
}
And with map :
ListObj.map(obj => { 'value' = obj })
Suggestions ?

You can use .map() for this. It passes the index into the callback.
myArray = myArray.map((str, index) => ({ value: str, id: index + 1 }));

Related

Is there any other way to check multiple values are present in array of object?

I have the below array of objects and I want to check if two different users are present in this array .if present i have to run some logic
let result = [{"name": "ABC"},{"name": "CDE"},{"name": "FGH"},{"name": "XYZ"}];
var newArr = [];
var hasMatch = result.filter(function(val) {
if (val.name == "FGH"){
newArr.push(val)
} else if (val.name == "ABC") {
newArr.push(val)
}
});
console.log(newArr)
if (newArr.length == 2) {
//do logic
}
It's working as expected but I'm looking for a different approach for this. could someone advise?
Not optimized for speed, but does the job
let arr = [
{
"name": "ABC"
},
{
"name": "CDE"
},
{
"name": "FGH"
},
{
"name": "XYZ"
}
];
let users = ["ABC", "XYZ"]
let hasAllUsers = users.every(user => arr.some(item => item.name == user))
console.log(hasAllUsers)
// if(hasAllUser) {...}
It's a pretty roundabout way to zero in on the logic you're trying to express. Note how the result in hasMatch is never even used. That's really all you're looking for, does the array "have the values".
There's no need to push values to another array and check if that array has values. Just check of the original array has them.
Which could be as simple as:
let result = [{"name": "ABC"},{"name": "CDE"},{"name": "FGH"},{"name": "XYZ"}];
if (result.filter(r => r.name === "FGH" || r.name === "ABC").length === 2) {
// do logic
}
Or if you want to refactor the condition into a variable:
let result = [{"name": "ABC"},{"name": "CDE"},{"name": "FGH"},{"name": "XYZ"}];
let hasMatch = result.filter(r => r.name === "FGH" || r.name === "ABC").length === 2;
if (hasMatch) {
// do logic
}
Or a bit more verbose for clarity:
let result = [{"name": "ABC"},{"name": "CDE"},{"name": "FGH"},{"name": "XYZ"}];
let filteredResult = result.filter(r => r.name === "FGH" || r.name === "ABC");
let hasMatch = filteredResult.length === 2;
if (hasMatch) {
// do logic
}
You can simply create another array with the valid users and filter your array to match each items that are this array.
This can be done using the Array#includes method
const users = [{"name": "ABC"},{"name": "CDE"},{"name": "FGH"},{"name": "XYZ"}];
const validUsers = ["ABC", "FGH", "AnotherUser"];
const matchUsers = users.filter(user => validUsers.includes(user.name))
console.log(matchUsers)
You could count the wanted names.
const
data = [{ name: "ABC" }, { name: "CDE" }, { name: "FGH" }, { name: "XYZ" }],
names = ['ABC', 'FGH'],
result = data.reduce((t, { name }) => t + names.includes(name), 0);
console.log(result);
Try using a named function and pass in the array, key, and one or more values with the rest operator ...values. Use .flatMap() to filter with
[...values].includes(obj[key])
// ["ABC", "XYZ"].includes(obj.name)
and any non-match returns an empty array []. The final return is an array with a sub-array and the length of said sub-array.
const result = [["ABC", "XYZ"], 2]
// result[0][0] = "ABC"
// result[0][1] = "XYZ"
// result[1] = 2
const arr = [{"name": "ABC"},{"name": "CDE"},{"name": "FGH"},{"name": "XYZ"}];
function hasMatch(array, key, ...values) {
const result = array.flatMap((obj, idx) =>
[...values].includes(obj[key]) ? obj : []);
return [result, result.length];
}
console.log(hasMatch(arr, "name", "ABC", "XYZ"));
console.log(hasMatch(arr, "name", "FGH", "IJK", "LMN", "ABC", "XYZ"));

Increase count property on object if duplicate value exists in an array

I would like to take list variable and get it to the point that updated list is at but am unsure how.
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const updatedList = [{name:'apple', count:2},{name:'banana', count: 1}];
Maybe this example will help you ?
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const updatedList = Object.values(list.reduce(
(map, el) => {
map[el.name] ? map[el.name].count++ : map[el.name] = { ...el,
count: 1
};
return map;
}, {}
));
console.log(updatedList);
function uptadeLi(list,item,quant) {
// body...
for( i in list){
if (list[i].name === item){
list[i].count = quant
}
}
}
With that function you can set each one of the elements of lists , be sure to put the name of item as string
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const res = list.reduce((sub,value)=>{
const index= sub.findIndex(i => i.name===value.name)
if(index !==-1)
sub[index].count++
else
sub.push({name:value.name,count:1})
return sub
},[])
console.log(res)
Use .reduce() method to evaluate the count for each item into an object with unique keys:
{ "apple": 2, "banana": 1 }
Then use Object.entries() to convert this into the following array:
[ ["apple", 2], ["banana", 1] ]
Finally, use .map() method to produce:
[ {"name": "apple", "count": 2}, {"name": "banana", "count": 1} ]
DEMO
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const updatedList = Object.entries(
list.reduce(
(acc,cur) => ({...acc,[cur.name]:(acc[cur.name] || 0) + 1}),
{})
)
.map(([name,count]) => ({name,count}));
console.log( updatedList );

How to create an object with properties in the array from the string?

I want to create objects with properties in an array by string. I'm extracting "name" from string and "data" without round brackets and trying to create objects in the array with the property "name"
and property "data". But actual result differs from expected, please help to solve
const names = ["name1 /2 (data1)", "name1 /2 (data2)", "name2 /1 (data1)"]
const flag = true
names.forEach(name => {
console.log(getStructuredDataFromNames(name))
})
function getStructuredDataFromNames(name) {
const names = {}
// extract name from string and conver to valid format - 'name1'
const formattedName = name.substr(0, name.indexOf("/")).replace(/\s+/g, "")
// extract data from string and conver to valid format - 'data1'
const formattedData = name.match(/\((.*)\)/).pop()
const reference = {
formattedData,
flag
}
// if no name then create a new property by this name
if (!names[name]) {
names[name] = [{
data: [reference]
}]
} else {
// if object have name but name have more then 1 data then push this data to array
names[name].push(reference)
}
const result = Object.keys(names)
return result.map(el => ({
name: el,
data: names[el]
}))
}
Expected result
[{
name: "name1",
data: [{
flag: true,
formattedData: "data1"
},
{
flag: true,
formattedData: "data2"
}
]
},
{
name: "name2",
data: [{
flag: true,
formattedData: "data1"
}]
}
]
Although the code is not that clean, it can do the job.
My flow is first to remove the spaces, and then split the name and the data, remove the number before the data and remove (). If "formattedNames" already have the same "name" object, push the data to the "name" object.
const names = ["name1 /2 (data1)", "name1 /2 (data2)", "name2 /1 (data1)"]
const formattedNames = []
names.forEach(value =>{
const processedName = value.replace(/ /g,'').split("/")
const formattedName = formattedNames.find((object)=>{ return object.name === processedName[0]})
const formattedData = processedName[1].split("(")[1].replace(")","")
if (!formattedName) {
formattedNames.push({name: processedName[0],data: [{flag: true, formattedData}]})
} else {
formattedName.data.push({flag: true, formattedData})
}
})
console.log(formattedNames)
Here is a really inefficient way to do it
var names2 = ["name1 /2 (data1)", "name1 /2 (data2)", "name2 /1 (data1)"]
var flag2 = true
var result2 = names2.map(x =>
{
return {
name: x.split(" ")[0],
data:
[
{
flag: flag2,
formattedData: x.match(/\((.*)\)/).pop()
}
]
}
})
result2.forEach((el, index, arr) =>
{
let el2 = arr.filter(x => x.name == el.name)[0];
if(el2 == el)
return;
el2.data = el2.data.concat(el.data);
delete arr[index];
})
result2 = result2.filter(x => true);
console.log(result2);

Form Array of objects using an array and an object

I have an object and an array of following kind
var sourceObject = { "item1" : 15 , "item2" : 20 " }
var feature = ["field1", "field2" ]
I am trying to convert the above object into an array of objects.
Number of items in the object as well as the array will be same
Resultant array of objects should like this:
var result = [ { "name" : "field1" , "value" : 15 } , { "name" : "field2" , "value": 20 }]
The ultimate goal is to read it from the sourceObject to get the each value and then pick each value from the "feature" array toform an object
Approach I have tried so far:
let result = [];
for (let value of Object.values(sourceObject)) {
let row = { "field" : "XYZ" , "value": value };
tableData.push(row);
}
Loop over the keys of sourceObject and then use Array.map()
var sourceObject = {
"item1": 15,
"item2": 20
}
var feature = ["field1", "field2"]
var result = Object.keys(sourceObject).map((key, index) => {
return {
name: feature[index],
value: sourceObject[key]
}
});
console.log(result);
Your object doesn't always guarantee order, so using .values(), .keys() etc... won't necessarily always guarantee your result. Instead, you can get the number from your fieldN string using a regular expression. Here N represents the itemN you want to retrieve from your object. Using this, you can .map() each fieldN to an object from your sourceObject.
See example below:
const sourceObject = { "item1" : 15 , "item2" : 20 };
const feature = ["field1", "field2" ];
const res = feature.map((name, i) => {
const [n] = name.match(/\d+$/g);
const value = sourceObject[`item${n}`];
return {name, value};
});
console.log(res);

array map, map array as a key of an array

I know the title might sounds confusing, but i'm stuck for an hour using $.each. Basically I have 2 arrays
[{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
and [{"toy":"car","section_id":1},{"tool":"knife","section_id":1},{"weapons":"cutter","section_id":2}];
How do I put one into another as a new property key like
[{
"section_name": "abc",
"id": 1,
"new_property_name": [{
"toy": "car"
}, {
"tool": "knife"
}]
}, {
"section_name": "xyz",
"id": 2,
"new_property_name": [{
"weapon": "cutter"
}]
}]
ES6 Solution :
const arr = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
const arr2 = [{"toy":"car","id":1},{"tool":"knife","id":1},{"weapons":"cutter","id":2}];
const res = arr.map((section,index) => {
section.new_property_name = arr2.filter(item => item.id === section.id);
return section;
});
EDIT : Like georg mentionned in the comments, the solution above is actually mutating arr, it modifies the original arr (if you log the arr after mapping it, you will see it has changed, mutated the arr and have the new_property_name). It makes the .map() useless, a simple forEach() is indeed more appropriate and save one line.
arr.forEach(section => {
section.new_property_name = arr2.filter(item => item.id === section.id));
});
try this
var data1 = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
var data2 = [{"toy":"car","id":1},{"tool":"knife","id":1},{"weapons":"cutter","id":2}];
var map = {};
//first iterate data1 the create a map of all the objects by its ids
data1.forEach( function( obj ){ map[ obj.id ] = obj });
//Iterate data2 and populate the new_property_name of all the ids
data2.forEach( function(obj){
var id = obj.id;
map[ id ].new_property_name = map[ id ].new_property_name || [];
delete obj.id;
map[ id ].new_property_name.push( obj );
});
//just get only the values from the map
var output = Object.keys(map).map(function(key){ return map[ key ] });
console.log(output);
You could use ah hash table for look up and build a new object for inserting into the new_property_name array.
var array1 = [{ "section_name": "abc", "id": 1 }, { "section_name": "xyz", "id": 2 }],
array2 = [{ "toy": "car", "section_id": 1 }, { "tool": "knife", "section_id": 1 }, { "weapons": "cutter", "section_id": 2 }],
hash = Object.create(null);
array1.forEach(function (a) {
a.new_property_name = [];
hash[a.id] = a;
});
array2.forEach(function (a) {
hash[a.section_id].new_property_name.push(Object.keys(a).reduce(function (r, k) {
if (k !== 'section_id') {
r[k] = a[k];
}
return r;
}, {}));
});
console.log(array1);
Seems like by using Jquery $.merge() Function you can achieve what you need. Then we have concat function too which can be used to merge one array with another.
Use Object.assign()
In your case you can do it like Object.assign(array1[0], array2[0]).
It's very good for combining objects, so in your case you just need to combine your objects within the array.
Example of code:
var objA = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
var objB = [{"toy":"car","section_id":1},{"tool":"knife","section_id":1},{"weapons":"cutter","section_id":2}];
var objC = Object.assign({},objA[0],objB[0]);
console.log(JSON.stringify(objC));// {"section_name":"abc","id":1,"toy":"car","section_id":1}
For more info, you can refer here: Object.assign()
var firstArray = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}],
secondArray = [{"toy":"car","section_id":1},{"tool":"knife","section_id":1},{"weapons":"cutter","section_id":2}];
var hash = Object.create(null);
firstArray.forEach(s => {
hash[s.id] = s;
s['new_property_name'] = [];
});
secondArray.forEach(i => hash[i['section_id']]['new_property_name'].push(i));
console.log(firstArray);

Categories