I would like to know how to add existing matched values in object and add the remaining values in javascript
for example, i need to merge_obj with my_obj having id '1' , matched values targetAmount only replace and remaining properties need to add
I tried
var filtervalue = my_obj.filter((e)=>e.id == "1").map((e)=>Object.assign({},e[0], merge_obj));
const merge_obj = {
targetAmount: 50688.97,
type: "REGULAR"
}
const my_obj = [
{
id: "1",
logo: "img1.png",
name: "fund",
speed: "1 Days",
targetAmount: "2000"
},
{
id: "2",
logo: "img2.png",
name: "transfer",
speed: "1 Days",
targetAmount: "3000"
},
]
Expected Output:
var my_obj = [
{
id: "1",
logo: "img1.png",
name: "fund",
speed: "1 Days",
targetAmount: 50688.97,
type: "REGULAR",
},
{
id: "2",
logo: "img2.png",
name: "transfer",
speed: "1 Days",
targetAmount: "3000",
},
]
This can be achieved my using the array map method to iterate through the array of objects, checking if the id is equivalent to '1', followed by using ES6's spread syntax to 'merge' the objects.
const result = my_obj.map(obj => {
if (obj['id'] === '1') {
return {...obj, ...merge_obj}
} else {
return obj;
}
})
console.log(result)
Also, just a quick advice, try to use const and let instead of var!
Just merge the first one by checking id:
var my_obj = [{
id: "1",
logo: "img1.png",
name: "fund",
speed: "1 Days",
targetAmount: "2000"
},
{
id: "2",
logo: "img2.png",
name: "transfer",
speed: "1 Days",
targetAmount: "3000"
},
]
var merge_obj = {
targetAmount: 50688.97,
type: "REGULAR"
};
var new_obj = my_obj.map(e => {
if (e.id == "1") {
Object.keys(merge_obj).forEach(key => e[key] = merge_obj[key]);
}
return e;
});
console.log(new_obj);
.as-console-wrapper { max-height: 100% !important; top: auto; }
If you want to mutate the original just loop over your array and assign directly
var my_obj = [{
id: "1",
logo: "img1.png",
name: "fund",
speed: "1 Days",
targetAmount: "2000"
},
{
id: "2",
logo: "img2.png",
name: "transfer",
speed: "1 Days",
targetAmount: "3000"
},
]
var merge_obj = {
targetAmount: 50688.97,
type: "REGULAR"
};
my_obj.forEach(e=> {if(e.id==='1') Object.assign(e, merge_obj)})
console.log(my_obj)
Change the object accessor in the map function from e[0] to e only, and check if that works.
i.e.
var filtervalue = myList.filter((e)=>e.id == "1").map((e)=>Object.assign({}, e, merge_obj));
Also, you need to check your variable names properly whether its my_obj or myList.
Related
With a API call i'm receiving a response like below
[
{
stationId: "10"
name: "Jinbaolai"
group: {id: "18", stationGroupName: "Ali"}
},
{
stationId: "13"
name: "Stack"
group: {id: "18", stationGroupName: "Ali"}
},
{
stationId: "20"
name: "Overflow"
group: {id: "19", stationGroupName: "Baba"}
}
]
As you can see first two records consist with the same group. I want to group these data according to the group. So for example it should look like this
[
{
groupId: "18",
groupName : "Ali",
stations : [
{
stationId: "10",
name: "Jinbaolai"
},
{
stationId: "13",
name: "Stack"
}
]
},
{
groupId: "19",
groupName : "Baba",
stations : [
{
stationId: "20",
name: "Overflow"
},
]
}
]
I want to do the grouping logic in my reducer where i also set the full data array that is shown in the beginning of the question.
case EVC_SUCCESS:
return {
...state,
chargingStations: action.evcData.chargingStations,
chargingStationGroups: //This is where my logic should go. ('action.evcData.chargingStations' is the initial data array)
tableLoading: false
}
How can i do this? I tried something using filter but not successful.
The best way to do this is to use Array.prototype.reduce()
Reduce is an aggregating function where you put in an array of something and get a single vaule back.
There may be a starting value as last parameter like I used {}.
The signature is reduce(fn, startingValue) where fn is a function taking two parameters aggregate and currentValue where you return the aggregate in the end.
const groupData = (data)=> {
return Object.values(data.reduce((group,n)=>{
if (!group[n.group.id]){
group[n.group.id] = {
groupId:n.group.id,
groupName: n.group.stationGroupName,
stations:[]}
}
group[n.group.id].stations.push({
stationID: n.stationId,
name: n.name
})
return group;
}, {}))
}
Here is the fiddle
A simple JS algorithm can do that for you
const list = [
{
stationId: "10",
name: "Jinbaolai",
group: {id: "18", stationGroupName: "Ali"}
},
{
stationId: "13",
name: "Stack",
group: {id: "18", stationGroupName: "Ali"}
},
{
stationId: "20",
name: "Overflow",
group: {id: "19", stationGroupName: "Baba"}
}
];
const groups = {};
list.forEach((item) => {
const groupId = item.group.id;
const group = groups[groupId] || {groupId: groupId, groupName: item.group.stationGroupName, stations: []};
group.stations.push({stationId: item.stationId, name: item.name});
groups[groupId] = group;
});
const groupedArray = Object.keys(groups).map((groupId) => groups[groupId]);
console.log(groupedArray); // This will be the output you want
I think chaining multiple functions will work.
const stations = [
{
"stationId": 10,
"name": "Jinbaolai",
"group": {"id": "18", "stationGroupName": "Ali"}
},
{
"stationId": 13,
"name": "Stack",
"group": {"id": 18, "stationGroupName": "Ali"}
},
{
"stationId": 20,
"name": "Overflow",
"group": {"id": "19", "stationGroupName": "Baba"}
}
]
const groups = _.chain(stations)
.groupBy((station) => { return station.group.id })
.map((values, key) => {
return {
"groupId": _.first(values).group.id,
"groupName": _.first(values).group.id,
"stations": _.map(values,(value)=>{ return { "stationId": value.stationId, "name": value.name } })
}
})
console.log("groups",groups)
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
I would like to know how to remove the object by property in nested array object
I have whole list of object in sampleobj, compare each id with apitrans, apifund, if success is false, remove obj in sampleobj
Remove the object if the success is false, in sampleobj.
I have tried:
var result = sampleobj.foreach(e=>{
if(e.id === "trans" && apitrans.success== true){
Object.assign(e, apitrans);
}
if(e.id === "fund" && apifund.success== true){
Object.assign(e, apifund);
}
// if success false remove the object.
})
//inputs scenario 1
var sampleobj=[{
id: "trans",
amount: "100",
fee: 2
},
{
id: "fund",
amount: "200",
fee: 2
}]
var apitrans =
{
success: true,
id: "trans",
tamount: "2000",
fee: "12"
}
var apifund =
{
success: false,
id: "fund",
tamount: "4000",
fee: "10"
}
//inputs scenario 2 how to do same if property name differs
if error, status error, or success false remove obj in sampleobj
var sampleobj=[{
id: "trans",
amount: "100",
fee: 2
},
{
id: "fund",
amount: "200",
fee: 2
},
{ id: "insta", amount: "400", fee: 2 }
]
var apitrans = {success: true,id: "trans",tamount: "2000",fee: "12"}
var apiinsta = { errors: [{code:"error.route.not.supported"}],id: "insta",tamount: "2000",fee: "12"}
var apifund = { status: "error", id: "fund", tamount: "4000", fee: "10" }
var sampleobj=[{
//Expected Output
result: [
{
id: "trans",
amount: "100",
fee: 2
}
]```
You can use filter() to remove elements from array.
Create a helper function(func) which takes two objects as parameter and compare id property of both and check success property of one of them.
Then use filter() of the given array and put both given objects array [apitrans,apifund].
Then use some() method on [apitrans,apifund] and check if any of them have id equal the current element using Helper Function.
var arr=[ { id: "trans", amount: "100", fee: 2 }, { id: "fund", amount: "200", fee: 2 } ]
var apitrans = {success: true,id: "trans",tamount: "2000",fee: "12"}
var apifund = { success: false, id: "fund", tamount: "4000", fee: "10" }
const func = (obj1,obj2) => obj1.id === obj2.id && obj2.success
const res = arr.filter(x => [apitrans,apifund].some(a => func(x,a)));
console.log(res)
You can filter out your array with conditions i.e filter gives you new array instead of changing the original array
var arr = [{
id: "trans",
amount: "100",
fee: 2
},
{
id: "fund",
amount: "200",
fee: 2
}
]
var apitrans = {
success: true,
id: "trans",
tamount: "2000",
fee: "12"
}
var apifund = {
success: false,
id: "fund",
tamount: "4000",
fee: "10"
}
var filter = arr.filter(function(item) {
//console.log(item);
if (item.id === apitrans.id && apitrans.success) {
return item
}
});
console.log(filter);
Or if you want an original array to be modified instead of getting a new array, you can use your given approach with some update i.e
var arr = [{
id: "trans",
amount: "100",
fee: 2
},
{
id: "fund",
amount: "200",
fee: 2
}
]
var apitrans = {
success: true,
id: "trans",
tamount: "2000",
fee: "12"
}
var apifund = {
success: false,
id: "fund",
tamount: "4000",
fee: "10"
}
arr.forEach(e => {
if (e.id === "trans" && apitrans.success == true) {
Object.assign(e, apitrans);
} else if (e.id === "fund" && apifund.success == true) {
Object.assign(e, apifund);
} else {
// if success false remove the object.
var index = arr.indexOf(e);
arr.splice(index, 1);
}
})
console.log("resulted original arr", arr)
I would like to know how to assign values to object property in nested object by id=insta in javascript
I have a two objects, I need apply one object property to another using javascript
I got stuck and dont know how to proceed,
obj1.forEach(e=> {if(e.id==='insta') Object.assign(e, obj2)})
var obj1 = [
{
id: "insta",
rate: "2.4",
fee: "0",
amount: "400"
},
{
id: "trans",
rate: "1.4",
fee: "0",
amount: "200"
}
]
var obj2 =
{
data: {
rate_value: "4.4",
fee_value: "10",
targetamount: "5000",
country_code: "SG"
}
}
Expected Output:
res= [
{
id: "insta",
rate: "4.4",
fee: "10",
amount: "5000",
country_code: "SG"
}
]
As your expected output shows you only want the items whose id="insta" so use filter() to get those. Then use map() and create a temporary object inside map. And return the combined object using Spread Operator.
Note: You need to create another object because properties name in obj2 and array are different.
var obj1 = [ { id: "insta", rate: "2.4", fee: "0", amount: "400" }, { id: "trans", rate: "1.4", fee: "0", amount: "200" }]
var obj2 = { data: { rate_value: "4.4", fee_value: "10", targetamount: "5000", country_code: "SG" } }
const res = obj1.filter(x => x.id === "insta").map(x => {
const {data} = obj2
let temp = {
rate : data.rate_value,
fee : data.fee_value,
amount : data.targetamount,
country_code : data.country_code
}
return {...x,...temp}
})
console.log(res)
We can use the reduce method to reduce the array to the result we intend to. Here I add the the if condition and mapping values from obj2 in the callback of the reduce method. Basically the filtering and mapping is done, inside the reduce callback method.
var obj1 = [{
id: "insta",
rate: "2.4",
fee: "0",
amount: "400"
},
{
id: "trans",
rate: "1.4",
fee: "0",
amount: "200"
}
]
var obj2 = {
data: {
rate_value: "4.4",
fee_value: "10",
targetamount: "5000",
country_code: "SG"
}
}
const result = obj1.reduce((acc, curr) => {
if (curr.id === 'insta') {
acc.push({
...curr,
rate: obj2.data.rate_value,
fee: obj2.data.fee_value,
amount: obj2.data.targetamount,
country_code: obj2.data.country_code
})
}
return acc;
}, []);
console.log(result);
First of all, you can Array.filter the array to contain object with id = "insta" then apply the data from obj2 to each one of the items using Array.map.
Something like that:
var obj1 = [{
id: 'insta',
rate: '2.4',
fee: '0',
amount: '400',
},
{
id: 'trans',
rate: '1.4',
fee: '0',
amount: '200',
},
];
var obj2 = {
data: {
rate_value: '4.4',
fee_value: '10',
targetamount: '5000',
country_code: 'SG',
},
};
const result = obj1
.filter(item => item.id === 'insta')
.map(item => ({
id: item.id,
rate: obj2.data.rate_value,
fee: obj2.data.fee_value,
amount: obj2.data.targetamount,
country_code: obj2.data.country_code,
}));
console.log(result)
I have two arrays (and the length can be in 1000s):
I want my array to replace status to the status of array 2. Here is the output example:
[{
value: 123,
status: 'demo',
type: '...'
},
{value: 2335,
status: 'demo2',
type: 'xxx'
}]
As we can see it needs to get the status from another array and replace it. What are the most possible efficient solutions for this? As this array can be very large. I don't know a good approach to solve this problem.
Length and sort order can be different, I need to replace array1's status by the array2's status,
By linking Array1's status and Array2's id
My actual Data
[
{
"id": "55",
"status": "2",
"type": "COD",
"value": "5038.2",
},
{
"id": "56",
"status": "2",
"type": "COD",
"value": "5398.2",
},
{
"id": "57",
"status": "2",
"type": "COD",
"value": "10798.2",
}
]
Array 2
[
{
"id": "1",
"status": "Awaiting Confirmation",
},
{
"id": "2",
"status": "Confirmed",
},
{
"id": "3",
"status": "Awaiting Shipment",
},
{
"id": "4",
"status": "Awaiting Pickup",
},
{
"id": "5",
"status": "Shipped",
},
{
"id": "6",
"status": "Delivered",
},
{
"id": "7",
"status": "Cancelled",
},
{
"id": "8",
"status": "Refund Requested",
},
{
"id": "9",
"status": "Refunded",
}
Things i have tried...I have used lodash and a for loop to achieve this
const output = [];
for (let i = 0; i < array1.length; i++) {
const statuscode = array1[i].status;
const result = _.find(array2, { id: statuscode });
output.push({
value: array1[i].value,
status: result.status,
type: array1[i].type
});
}
console.log(output);
For high performance, transform one of the arrays to a Map first. Map lookups are very efficient:
const input1 = [{
value: 123,
status: 1,
type: 'COD',
},
{
value: 2335,
status: 2,
type: 'COD',
},
{
value: 222,
status: 3,
type: 'COD',
}
];
const input2 = [{
id: 1,
status: 'demo'
},
{
id: 2,
status: 'demo2'
}, {
id: 3,
status: 'demo3'
}
];
const map2 = new Map(Object.values(input2).map(({ id, status }) => [id, status]));
const output = input1.map(({ status, ...rest }) => {
const otherStatus = map2.get(status);
return { ...rest, status: otherStatus };
});
console.log(output);
Code readability generally matters more than speed, but if you wanted, you could transform the .map transformation into a for loop as well:
const input1 = [{
value: 123,
status: 1
},
{
value: 2335,
status: 2
},
{
value: 222,
status: 3
}
];
const input2 = [{
id: 1,
status: 'demo'
},
{
id: 2,
status: 'demo2'
}, {
id: 3,
status: 'demo3'
}
];
const map1 = new Map(Object.values(input1).map(({ value, status }) => [status, value]));
const output = [];
for (let i = 0; i < input2.length; i++) {
const { id, status } = input2[i];
output.push({ value: map1.get(id), status });
}
console.log(output);
A simple for loop would do:
for (let i = 0; i < array1.length; i++) {
array1[i].status = array2[i].status;
}
This of course assumes that the length and the order of the two arrays is the same.
EDIT
Alternative solution using Array.prototype.find and taking into account different lengths and orders.
for (let i = 0; i < array1.length; i++) {
const buffer = array1[i];
buffer.status = array2.find(x => x.id === buffer.status).status;
}
Also, I would highly recommend giving priority to readability over premature optimisation
Is it possible to slice single property from array of objects like
[{"name":"Bryan","id":016, "counter":0}, {"name":"John","id":04, "counter":2}, {"name":"Alicia","id":07, "counter":6}, {"name":"Jenny","id":015, "counter":9}, {"name":"Bryan","id":016, "counter":0}, {"name":"Jenny","id":015, "counter":9}, {"name":"John","id":04, "counter":2}, {"name":"Jenny" ,"id":015, "counter":9}];
I'm trying to slice name from every object and count number of the same elements (there are 3 objects with name Jenny) in order to achieve the following structure:
[{"name":"Bryan","Number":2},
{"name":"John","Number":2},
{"name":"Alicia","Number":1},
{"name":"Jenny","Number":3}]
Do you want to ignore the id and counter props already present?
You could create an object to keep track of the unique names, and convert back to an array in the end:
var data = [{"name": "Bryan", "id": 016, "counter": 0}, { "name": "John", "id": 04, "counter": 2}, { "name": "Alicia", "id": 07, "counter": 6}, { "name": "Jenny", "id": 015, "counter": 9}, { "name": "Bryan", "id": 016, "counter ": 0}, { "name": "Jenny", "id": 015, "counter ": 9}, { "name": "John", "id": 04, "counter": 2}, { "name": "Jenny", "id": 015, "counter": 9}];
var result = data.reduce(function(result, item) {
if (!result[item.name]) {
result[item.name] = {
name: item.name,
counter: 0
};
}
result[item.name].counter += 1;
return result;
}, {});
console.log(Object.keys(result).map(function(key) { return result[key] }));
You could use a hash table as a reference to the counted names.
var data = [{ name: "Bryan", id: "016", counter: 0 }, { name: "John", id: "04", counter: 2 }, { name: "Alicia", id: "07", counter: 6 }, { name: "Jenny", id: "015", counter: 9 }, { name: "Bryan", id: "016", counter: 0 }, { name: "Jenny", id: "015", counter: 9 }, { name: "John", id: "04", counter: 2 }, { name: "Jenny", id: "015", counter: 9 }],
grouped = [];
data.forEach(function (a) {
if (!this[a.name]) {
this[a.name] = { name: a.name, Number: 0 };
grouped.push(this[a.name]);
}
this[a.name].Number++;
}, Object.create(null));
console.log(grouped);
Give this a shot. We create a dictionary of names with their counts called nameDict, and iterate through the list to count them.
var arr = [{"name":"Bryan","id":"016", "counter":0}, {"name":"John","id":"04", "counter":2}, {"name":"Alicia","id":"07", "counter":6}, {"name":"Jenny","id":"015", "counter":9}, {"name":"Bryan","id":"016", "counter":0}, {"name":"Jenny","id":"015", "counter":9}, {"name":"John","id":"04", "counter":2}, {"name":"Jenny","id":"015", "counter":9}];
var nameDict = {};
for(var i = 0; i < arr.length; i++)
{
var name = arr[i].name;
if(nameDict[name] == undefined){
//haven't encountered this name before so we need to create a new entry in the dict
nameDict[name] = 1
} else {
//otherwise increment the count
nameDict[name] += 1
}
}
console.log(JSON.stringify(nameDict));