Compare different collections and and take a value - javascript

I want to find a nice / elegant (maybe using lodash) way to do compare 2 different colections and on equality (according to my defenition of equal) take some value from 1 collection and another value from the other collection and map it to a new collection, like so:
const filter1 = [{
columnName : "date",
value : "12/5"
},
{
columnName : "age",
value : "12"
}]
const filter2 = [{
valueName : "age",
displayName: "Age"
},
{
valueName : "date",
displayName: "DateD"
}]
filter1.map((val) => ({
displayName: filter2.find(filter => filter.valueName === val.columnName).displayName,
value : val.value
}))
to get:
[{
displayName: "DateD",
value: "12/5"
}, {
displayName: "Age",
value: "pa"
}]

Convert the 2nd array to a Map using valueName as the rest of the object as the value. Create the new array by mapping the 1st array, getting the items from the Map using columnName and merging it with the values from the 1st array using object spread.
const fn = (arr1, arr2) => {
const arr2Map = new Map(arr2.map(({ valueName, ...rest }) => [valueName, rest]))
return arr1.map(({ columnName, ...rest }) => ({
...arr2Map.get(columnName),
...rest
}))
}
const filter1 = [{"columnName":"date","value":"12/5"},{"columnName":"age","value":"12"}]
const filter2 = [{"valueName":"age","displayName":"Age"},{"valueName":"date","displayName":"DateD"}]
const result = fn(filter1, filter2)
console.log(result)

Related

How to delete an item from my Reducer Object?

I have an object in my reducer like this :
clientData : {
1080 : [{ID : 1111,name : 'John'},{ID : 2222,name : 'Stan'},],
1090 : [{ID : 3333,name : 'Adam'},{ID : 4444,name : 'Alan'},]
}
And I want to be able to delete an item (for example Stan with 2222 ID's)
The problem that is I don't have the key of my property (1080), and I don't have any idea how to achieve it.
I've tried the Object.values(object1) but it convert my object to array and I lost all my architecture.
Have you an idea please ?
Removing from existing objects might not be good, you can use Object.entries and filter to remove id.
If you want to change existing pass data to reducer
const data = {
1080: [
{ ID: 1111, name: "John" },
{ ID: 2222, name: "Stan" },
],
1090: [
{ ID: 3333, name: "Adam" },
{ ID: 4444, name: "Alan" },
],
};
const remove = (id, data) => {
const entries = Object.entries(data);
return entries.reduce((acc, [key, value]) => {
const newValue = value.filter((item) => item.ID !== id);
acc[key] = newValue;
return acc;
// return { ...acc, [key]: newValue };
}, {}); // for updating existing data here
};
console.log(remove(2222, data))

i can't get array b of object a with reduce in js

i can't get array b of object a with reduce in js
can you help me find the error?
const a = {
dias:"valor",
horas:"valor"
}
const b = campos.reduce((acc, el) => ([...acc, {
title: el, field: el
}]), {})
desired result = [
{ title: 'dias', field: 'dias' },
{ title: 'horas', field: 'horas' },
]
You can use Object.keys().
const a = {
dias: "valor",
horas: "valor",
};
const b = Object.keys(a).map((key) => ({ title: key, field: key }));
console.log(b);
If you want the value of the property as the field instead, you can use Object.entries():
const a = {
dias: "valor",
horas: "valor",
};
const b = Object.entries(a).map(([key, value]) => ({
title: key,
field: value,
}));
console.log(b);
As a note, the [key, value] syntax is called array destructuring.

How can I sort through an Axios response?

I am using Axios to execute a GET request to a public API, I need to combine the names if they are the same and add the values up to only show the top 20 (It's a large dataset) based on the highest to lowest amounts(ascending order).
Axios Response
[
{
name: "foo1",
value: "8123.30"
},
{
name: "foo1",
value: "2852.13"
},
{
name: "foo2",
value: "5132.23"
},
{
name: "foo1",
value: "1224.20"
},
{
name: "foo2",
value: "1285.23"
}
1200...
];
Expected Output
[
{ name: "foo1",
value: "12199.63" // from all combined "foo1" amounts in the dataset
},
{
name: "foo2",
value: "6417.46" // from all combined "foo2" amounts in the dataset
},
18..
]
I tried to do something like this....
const fetchData = () => {
return axios.get(url)
.then((response) => response.data)
};
function onlyWhatINeed() {
const newArr = []
return fetchData().then(data => {
const sortedData = data.sort((a, b) => parseFloat(a.value) - parseFloat(b.value));
// I need to loop through the dataset and add all the "values" up
// returning only the top 20 highest values in an array of those objects
newArr.push(sortedData)
})
}
But I am confused as to how to push this data to a new array of the sorted data (top 20 values in ascending order) and use this data in my web application. I am a bit new to creating REST APIs so if you could provide articles and/or resources so I can understand a little more that would be an awesome bonus!
You can combine the entries that share the same name using a map, then sort the map and keep the first twenty elements :
function onlyWhatINeed() {
const newArr = []
return fetchData().then(data => {
let map = new Map();
data.forEach(d => {
if(!map.has(d.name)) {
map.set(d.name, parseFloat(d.value));
} else {
map.set(d.name, map.get(d.name) + parseFloat(d.value));
}
})
return Array.from(map.entries()).sort((a, b) => a.value - b.value).slice(0, 20);
})
}
Since you're dealing with a large dataset, I recommend that you handle this server side instead of offloading the sorting to your clients.
async function fetchData(){
const { data } = await axios.get(url);
let newArr = []
data.forEach((e,i) => {
let index = newArr.findIndex(el => el.name === e.name);
if(index !== -1 ) newArr[index].value += parseFloat(e.value); //add to the value if an element is not unique
if(index === -1 ) newArr.push({...e, value: parseFloat(e.value)}); //push to the array if the element is unique and convert value to float
});
return newArr.sort((a,b) => a.value - b.value).slice(0,20);//returns an array of 20 elements after sorting
}
Please do more research on how to work with arrays and objects in general.
If you happen to already be using lodash, then here's a functional-style solution using lodash chaining. Probably not optimal performance, but could be useful for relatively small datasets.
const _ = require('lodash');
const data = [
{
name: "foo1",
value: "8123.30"
},
{
name: "foo1",
value: "2852.13"
},
{
name: "foo2",
value: "5132.23"
},
{
name: "foo1",
value: "1224.20"
},
{
name: "foo2",
value: "1285.23"
},
{
name: "foo3",
value: "1000.00"
},
{
name: "foo3",
value: "2000.00"
}
];
// 1. convert string values to floats
// 2. group by name
// 3. sum values by name
// 4. sort by descending value
// 5. take top 20
const output =
_(data)
.map(obj => ({
name: obj.name,
value: parseFloat(obj.value)
}))
.groupBy('name')
.map((objs, key) => ({
name: key,
value: _.sumBy(objs, 'value')
}))
.orderBy(['value'], 'desc')
.slice(0, 20)
.value();
console.log('output:', output);

How to flatten objects in JavaScript (with or without lodash)?

I have an object like
farmer:{
name: "First Name",
bank: {
id: 7
}
certifications: [
{
certificateNumber: {
id : 7
},
certificateNumber: {
id : 8
}
}
]
}
I have tried using lodash's set and unset method but that results in undefined values a lot often.I want to remove the id key from the above object completely
This is the result i want
farmer:{
name: "First Name",
bank: 7
certifications: [
{
certificateNumber: 7,
certificateNumber: 8
}
]
}
You can use lodash's _.transform() to iterate the structure recursively, and if an object has an id property, and its size (number of properties) is 1, replace the object with the id value.
Note: the certifications array is malformed and was changed to the following form [{certificateNumber:{id:7}},{certificateNumber:{id:8}}].
const fn = obj => _.transform(obj, (accumulator, value, key) => {
let val = value
if(_.has(value, 'id') && _.size(value) === 1) val = _.get(value, 'id')
else if(_.isObject(value)) val = fn(value)
accumulator[key] = val
})
const farmer = {"name":"First Name","bank":{"id":7},"certifications":[{"certificateNumber":{"id":7}},{"certificateNumber":{"id":8}}]}
const result = fn(farmer)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.js"></script>

Remove object from array of objects based on object key value

I have an object like
let arr = [
{isManaged: true, id:1},
{isManaged: false, id:2},
{isManaged:false, id:3}
]
to get the values which are true, i do
arr.map(shift => ({
id: shift.id,
isPartnerManaged: shift.isManaged,
}))
but this will only return me the values where i true, now, I want to remove them from the array of objects. I tried to use the array.pop but i don't know what index to feed it. Any ideeas?
arr = arr.filter(shift => shift.isManaged);
You could filter the array and build new objects.
var array = [{ isManaged: true, id: 1 }, { isManaged: false, id: 2 }, { isManaged: false, id: 3 }],
result = array
.filter(({ isManaged }) => isManaged)
.map(({ isManaged: isPartnerManaged, id }) => ({ id, isPartnerManaged }));
console.log(result);

Categories

Resources