Map on Javascript object values without extra variable? - javascript

I'm using the following piece of code (which is working fine)
const result = {}
Object.keys(timers).forEach(key => {
result[key] = hydrate(timers[key])
})
return result
}
I'm wondering if this is possible in one method? So without having to fill the result object?

Convert to entries with Object.entries(), iterate the entries with Array.map() and hydrate the values, and convert back to an object with Object.fromEntries():
const fn = timers => Object.fromEntries(
Object.entries(timers).map(([k, v]) => [k, hydrate(v)])
)

Just use reduce
var timers = {
a: 2,
b: 3,
c: 4
}
const hydrate = x => 2*x
var result = Object.entries(timers).reduce((o, [key, value]) => {
o[key] = hydrate(value)
return o
}, {})
console.log(result)
without fat arrow
var timers = {
a: 2,
b: 3,
c: 4
}
function hydrate (x) { return 2 * x }
var result = Object.entries(timers).reduce(function(o, entry) {
o[entry[0]] = hydrate(entry[1])
return o
}, {})
console.log(result)

Related

How to get values from array of objects in javascript

I have an array of object from which I am trying to get values using map operator but I am getting the whole json objects all I want is just array of values.
Below is my code:
const obj = [
{
a: {
b: 'Paul',
}
},
{
c: 'Byeeee',
}
];
obj.map((val) => console.log(val));
what I am getting is
{ a: { b: 'Paul' } }
{ c: 'Byeeee' }
What I want is:
['Paul','Byeeee']
Someone let me know how can I get the desired output.
You can do this recursively. You can first start off by grabbing the values of your object, and then loop through those using .flatMap(). If you encounter a value that is an object, you can recursively grab the values of that object by recalling your function. Otherwise, you can return the value. The advantage of using .flatMap() here is that when the recursive call returns an array, we don't end up with inner arrays, but rather the array gets flattened into one resulting array:
const obj = [{ a: { b: 'Paul', } }, { c: 'Byeeee', } ];
const getValues = (obj) => {
return Object.values(obj).flatMap(val => Object(val) === val ? getValues(val) : val);
}
console.log(getValues(obj));
you can use the following solution.
const data = [{ a: { b: 'Paul' } }, { c: 'Byeeee' }];
const flatObjectValues = (obj, result) => {
// recursive function to get object values
const objValues = Object.values(obj);
if (objValues?.length > 0) {
objValues.map((v) => {
if (typeof v === 'object' && !Array.isArray(v)) {
flatObjectValues(v, result);
} else {
result.push(v);
}
return v;
});
}
};
const updatedData = [];
data.map((x) => flatObjectValues(x, updatedData));
console.log('updatedData: ', updatedData);
You can use recursion with array.reduce, like fellowing.
function getAllValues(objuct) {
return objuct.reduce((acc, curr) => {
if (typeof curr === 'object') {
return [...acc, ...getAllValues(Object.values(curr))];
}
return [...acc, curr];
}, []);
}
A recursive solution could be:
const arr = [{a: {b: "Paul",},},{c: "Byeeee",},];
const flatArrOfObjects = (arr) => {
const values = [];
for (const i in arr) flatObj(arr[i], values);
return values;
};
const flatObj = (obj, result) => {
for (const [key, value] of Object.entries(obj)) {
if (typeof value === "object") flatObj(value, result);
else result.push(value);
}
};
console.log(flatArrOfObjects(arr));

Javascript declarative/immutable version of 'maybe push'?

I have code like this:
A = [1,2,3]
if (condition) {A.push(4)}
A.push(5)
But my array is actually immutable so I can't do that. How can I do it all in one expression? I don't want a null value in the middle.
Here is one way:
A = [1, 2, 3, ...(condition ? [4] : []), 5]
If this is common in your codebase, and you want to keep undefined then you write a filter function with a sentinel.
const REMOVE = symbol('removeme')
const A = clean([1, 2, 3, condition ? 4 : REMOVE, 5])
function clean(arr) {return arr.filter(x=>x!==REMOVE)}
You can use the Writer monad here.
// type Writer t a = { value :: a, array :: [t] }
// pure :: a -> Writer t a
const pure = (value) => ({ value, array: [] });
// bind :: (Writer t a, a -> Writer t b) -> Writer t b
const bind = (writerA, arrow) => {
const writerB = arrow(writerA.value);
const array = [...writerA.array, ...writerB.array];
return { value: writerB.value, array };
};
// tell :: [t] -> Writer t ()
const tell = (array) => ({ value: undefined, array });
const writer = (gen) => {
const next = (data) => {
const { value, done } = gen.next(data);
return done ? value : bind(value, next);
};
return next(undefined);
};
const example = (condition) => writer(function* () {
yield tell([1, 2, 3]);
if (condition) yield tell([4]);
return tell([5]);
}());
console.log(example(true).array); // [1,2,3,4,5]
console.log(example(false).array); // [1,2,3,5]

Creates an object composed of the picked object properties: [duplicate]

This question already has answers here:
Filter object properties by key in ES6
(30 answers)
Closed 1 year ago.
I'm trying to create an object from object and list of properties.
const pick = (obj, ...fields) => {
return [...fields] = obj
};
How can I realise this?
Reduce the list of fields, and take the values from the original object:
const pick = (obj, ...fields) => fields.reduce((acc, field) => ({ ...acc, [field]: obj[field] }), {});
const obj = { a: 1, b: 2, c: 3 };
const result = pick(obj, 'a', 'c');
console.log(result);
You can use the in operator to ignore properties that don't exist on the original object:
const pick = (obj, ...fields) => fields.reduce((acc, field) => {
const value = obj[field];
if(field in obj) acc[field] = value;
return acc;
}, {});
const obj = { a: 1, b: 2, c: 3 };
const result = pick(obj, 'a', 'c', 'd');
console.log(result);
Try something like this:
const pick = (obj, ...fields) => Object.fromEntries(Object.entries(obj).filter(([k]) => fields.includes(k)))
Iterate through fields array and check if property is available in obj then put into final object which needs to be returned.
const pick = (obj, ...fields) => {
const finalObj = { };
for (field of fields) {
if (obj[field]) {
finalObj[field] = obj[field];
}
}
return finalObj;
};
const obj = { name: "test name", age: 25, title: "Mr.", city: "test city" };
console.log(pick(obj, "name", "age", "city", "other"));

how to make an array of strings into a key value pair object, making the value an array?

I've got an array of strings like so:
[
"hl7_file_type_1.msgtype",
"hl7_file_type_1.filename",
"hl7_file_type_2.msgtype",
"hl7_file_type_2.filename",
"hl7_file_type_3.msgtype",
"hl7_file_type_3.filename"
]
I am trying to convert this into a key value pair object like so (expected result):
{
"hl7_file_type_1": ["msgtype","filename"],
"hl7_file_type_2": ["msgtype","filename"],
"hl7_file_type_3": ["msgtype","filename"],
}
Here is how I am attempting this:
let tmp = {};
for (let i = 0; i < this.regexArray.length; i++){
let split = this.regexArray[i].split('.');
tmp[split[0].trim()] = split[1].trim();
}
console.log('Key Value')
console.log(tmp);
Here is what is returning:
{
"hl7_file_type_1": "filename",
"hl7_file_type_2": "filename",
"hl7_file_type_3": "filename"
}
How can I change my function to return the expected result like mentioned above
You can easily achieve this using reduce
const arr = [
"hl7_file_type_1.msgtype",
"hl7_file_type_1.filename",
"hl7_file_type_2.msgtype",
"hl7_file_type_2.filename",
"hl7_file_type_3.msgtype",
"hl7_file_type_3.filename",
];
const result = arr.reduce((acc, curr) => {
const [prop, type] = curr.split(".");
if (!acc[prop]) acc[prop] = [type];
else acc[prop].push(type);
return acc;
}, {});
console.log(result);
A bit of mapping and reducing should do it
const input = [
"hl7_file_type_1.msgtype",
"hl7_file_type_1.filename",
"hl7_file_type_2.msgtype",
"hl7_file_type_2.filename",
"hl7_file_type_3.msgtype",
"hl7_file_type_3.filename"
]
const result = input.map(i => i.split(".")).reduce( (acc,[key,value]) => {
return {
...acc,
[key]: [...(acc[key] || []), value]
}
},{});
console.log(result);
Simply map and then reduce.
const data = [
"hl7_file_type_1.msgtype",
"hl7_file_type_1.filename",
"hl7_file_type_2.msgtype",
"hl7_file_type_2.filename",
"hl7_file_type_3.msgtype",
"hl7_file_type_3.filename",
];
const res = data
.map((d) => d.split("."))
.reduce((r, [k, v]) => ((r[k] ??= []), r[k].push(v), r), {});
console.log(res);

Is there a way to set object keys from array value in one line

say I have an array like this:
const myArray = ['HP', 'QP', 'PS'];
And I'd like to have an object whose keys are myArray's values like
{ HP: 0, QP: 0, PS: 0 }
Is there a way to do the following in one line:
const myObj = {};
myArray.forEach(item => myObj[item] = 0);
Try using reduce:
const myArray = ['HP', 'QP', 'PS'];
const myObj = myArray.reduce((a, key) => Object.assign(a, { [key]: 0 }), {});
console.log(myObj);
In newer environments, you can also use Object.fromEntries:
const myArray = ['HP', 'QP', 'PS'];
const myObj = Object.fromEntries(myArray.map(key => [key, 0]));
console.log(myObj);
You could spread (spread syntax ...) mapped objects into one object with Object.assign.
var keys = ['HP', 'QP', 'PS'],
object = Object.assign(...keys.map(key => ({ [key]: 0 })));
console.log(object);
A one liner:
console.log(
['HP', 'QP', 'PS']
.map( v => ({[v]: 0}) )
.reduce( (p, n) => ({...p, ...n}), {} )
);
console.log(['HP', 'QP', 'PS'] .reduce( (p, n) => ({...p, [n] :0 }), {} ));

Categories

Resources