How to dynamically push an array using spread operator Javascript - javascript

[
{
"details": {
"name": "john",
"point": "20"
},
"list": {
"number": "30",
}
},
{
"details": {
"name": "doe",
"point": "25"
},
"list": {
"number": "30",
}
}
]
This is what i am trying to do, i am getting the data from the store and if the response is only one i use data = getData[0].details and if the response is more than one then i push the data using [...data, ...getData[1].details] if there are more than one data how can i achieve. thanks in advance
let data:any = [];
this.store
.pipe(
select(getData),
map((getData,i) => {
if (getData) {
data = [...data, ...getData[i].details]
}
return data;
})
)

I think you want to get an array of the details.
In this case you can say.
let data = [
{
"details": {
"name": "john",
"point": "20"
},
"list": {
"number": "30",
}
},
{
"details": {
"name": "doe",
"point": "25"
},
"list": {
"number": "30",
}
}
];
let details = data.map(a => a.details);
console.log(details);

I think i understand what you mean:
What I would do is map over your getData response and add to the original array on each iteration. It wont matter if there is 1 or many in the getData array:
getData.map(x => $data.push(x.details));

Related

How can i filter result if i have array in body

i have a payload
{
"category": "Mobile",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"1",
"2",
"3"
]
}
i want to find all object which have rating 1 or 2 or 3 and also have any location
Basically i am creating a filter for an ecommerce store i which we will get multiple location and multiple ratings as well so we will return only those object which have matched property. i am attaching a screenshot of UI for better understanding.
i want to run this filter with multiple location and multiple checked checkbox
You can do create a filter dynamically:
const { category, price, location, rating } = req.body;
const filter = {};
if (category) filter.category = category;
if (price) filter.price = { $gte: parseInt(price.from, 10), $lte: parseInt(price.to, 10) };
if (location?.length) filter.location = { $in: location };
if (rating?.length) filter.rating = { $in: rating };
const data = await Collection.find(filter);
If you want to filter your objects, you should use filter() from your array :
const arr = [{
"category": "Mobile1",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"1",
"2",
"3"
]
},
{
"category": "Mobile2",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"2",
"3"
]
}];
const result = arr.filter(el => el.rating.includes("1") || el.rating.includes("2") || el.rating.includes("3"));
console.log(result);

How to combine two JSON objects together [duplicate]

This question already has answers here:
How can I merge properties of two JavaScript objects dynamically?
(69 answers)
Closed 2 years ago.
I have two JavaScript obj like so:
const objOne = {
"firstname": "xzxz",
"lastname": "xzxzxzx"
};
const objTwo = {
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
};
and I want to combine them like below (not sure if "combine" is the appropriate word but hopefully make sense)
{
"firstname": "xzxz",
"lastname": "xzxzxzx",
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
}
so far I tried the below
let result = [];
results.push(objOne);
results.push(objTwo);
but surely the result is not the one I want and it make sense as I create an array and I push into both objects.
[
{
"firstname": "xzxz",
"lastname": "xzxzxzx"
},
{
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
}
]
const objOne = {
"firstname": "xzxz",
"lastname": "xzxzxzx"
};
const objTwo = {
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
};
const output = { ...objOne, ...objTwo };
console.log(output);
You could use Object.entries() to convert the objects into arrays and Object.fromEntries to convert it back into an object.
const objOne = {
"firstname": "xzxz",
"lastname": "xzxzxzx"
};
const objTwo = {
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
};
const combined = Object.fromEntries(
Object.entries(objOne)
.concat(Object.entries(objTwo))
);
console.log(combined);

Replacing Data in Array

I am working on an angular application. I have an array as follows:
[{
"Name": "Andy"
},
{
"Name": "Bayer"
},
{
"Name": "James"
},
{
"Name": "Doda"
}]
I have another array which containes data as follows:
[
{
"Name": "Andy",
"Id": "1",
"Time": "2020-06-19T11:02+00:00"
},
{
"Name": "Billy",
"Id": "2",
"Time": "2020-06-19T11:05+00:00"
},
{
"Name": "Ciena",
"Id": 5
"Time": "2020-06-19T11:05+00:00"
},
{
"Name": "Doda",
"Id": "4",
"Time": "2020-06-19T11:05+00:00"
}
]
I want a resultant array such that code should check if Name is present in first array, then it should copy data from second array for that Name and push it in resultant array. For example common name between above two array is Andy and Doda, so data from Andy and Doda should be pushed to resultant array as follows:
[{
"Name": "Andy",
"Id": "1",
"Time": "2020-06-19T11:02+00:00"
},
{
"Name": "Bayer"
},
{
"Name": "James"
},
{
"Name": "Doda",
"Id": "4",
"Time": "2020-06-19T11:05+00:00"
}]
At run time I may get many names so code should be generic. I was trying following code which I got over stackoverflow itself
this.newArray = _.map(this.resultantArray, item => {
const value = _.find(this.dataArray, ['Name', item]);
const obj = value ? value : {Name: item};
return obj;
});
But this code is not working as expected as it works fine for the first time but when data comes for second time it appends data to previous data. I want array to be populated again freshly every time I send data. Please help
You can do this with vanilla JS no need for lodash. You can first map it and inside that you can find the value from second array otherwise return the current object:
var arrayTwo = [ { "Name": "Andy", "Id": "1", "Time": "2020-06-19T11:02+00:00" }, { "Name": "Billy", "Id": "2", "Time": "2020-06-19T11:05+00:00" }, { "Name": "Ciena", "Id": "5", "Time": "2020-06-19T11:05+00:00" }, { "Name": "Doda", "Id": "4", "Time": "2020-06-19T11:05+00:00" } ];
var arrayOne = [{ "Name": "Andy"}, { "Name": "Bayer"}, { "Name": "James"}, { "Name": "Doda"}];
var result = arrayOne.map(val=>arrayTwo.find(p=>p.Name==val.Name) || val);
console.log(result);
Suppose first array name is First
First : any [] = [{"Name": "Andy"},{"Name": "Bayer"},{ "Name": "James"},{"Name": "Doda"}]
And Second array name is Second
Second : any[] = [{"Name": "Andy","Id": "1","Time": "2020-06-19T11:02+00:00"},{"Name": "Bayer"},{"Name": "James"},{"Name": "Doda","Id": "4","Time": "2020-06-19T11:05+00:00"}]
Now do looping and check each name of first if its exists in second copy from second and push in result array
result : any[] =[];
this.First.forEach((element) => {
let index = this.Second.findIndex((x) => element.Name== x.Name);
if (index > -1) {
let data = {
this.Second[index].Name,
this.Second[index].Id,
this.Second[index].time,
};
this.result.push(data);
}
}

Lodash to filter out an array of objects

I am trying to filter out a nested array of objects using lodash which is pretty straightforward but I am looking to avoid multiple calls.
I am looking to create 2 array of objects using a single lodash call/function. Looking to find object property "$isMultiAccount" if it exists put the whole object into one result set and if not put it to another ruleset.
Currently I am doing this with Lodash "has and filter" for first and for other "!has" which means same object is looped twice , as object is relatively large its creating bottleneck for speed
https://repl.it/repls/HomelyExpensiveTruetype
const item = {
"domains": [
{
"id": "dm11022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./Yes"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./No"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"conf": {
"isVpnBased":{
"accountType": "Primary"
}
}
}
]
}
}
}
]
}
/*
Expected result
output1 = [
{
"id": "dm11022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./Yes"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./No"
}
]
}
}
}
]
// $isMultiAccount account do not exist in this object
output2 = [
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"conf": {
"isVpnBased":{
"accountType": "Primary"
}
}
}
]
}
}
}
]
*/
const item = {
"domains": [
{
"id": "dm11022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./Yes"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./No"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"conf": {
"isVpnBased":{
"accountType": "Primary"
}
}
}
]
}
}
}
]
}
const [areMulti, areNotMulti] = _.reduce(item.domains, (current, next) => {
return _.has(next, ‘information.owner.others.$isMultiAccount’)
? [current[0].concat(next), current[1]]
: [current[0], current[1].concat(next)];
}, [[], []]);
console.log(areMulti);
console.log(areNotMulti);
Since item.domains.information.owner.others is an array, you need to tackle it as follows:
let multi = [];
let notMulti = [];
_.each(item.domains, function (obj) {
if (obj.information.owner.others.length && _.has(obj.information.owner.others[0], '$isMultiAccount'))
multi.push(obj);
else
notMulti.push(obj);
});
console.log(multi);
console.log(notMulti);
Unfortunately, you have to iterate over the domains array as well ass on the owner.others array to determine if the object with specific key sits inside.
So the algorithm has O(n*m) complexity.
If you ask for a lodash function seems that the partition method is what you're looking for
As docs says:
Creates an array of elements split into two groups, the first of which contains elements predicate returns truthy for, the second of which contains elements predicate returns falsey for. The predicate is invoked with one argument: (value).
So it will be like:
_.partition(
item.domains,
e => _.some(
_.get(e, 'information.owner.others'),
el => _.has(el,"$isMultiAccount")
)
);
Watch out - some hack available!
However, if the you're 100% sure that the element you're looking for will be always at specific index (for example it is supposed to be always as first element - so index 0) you can limit the algorithm to have linear complexity O(n) as only the size of the domains array will matter in terms of performance.
The hackish solution assuming fixed array index=0:
_.partition(
item.domains,
e => _.has(e, 'information.owner.others.0.$isMultiAccount')
);
NOTE
Using lodash makes code a bit easier to read but of course it creates some performance overhead anyway.

Underscore filter array of object using like query

I have the below Json.
{
"results": [
{
"id": "123",
"name": "Some Name"
},
{
"id": "124",
"name": "My Name"
},
{
"id": "125",
"name": "Johnson Johnson"
},
{
"id": "126",
"name": "Mike and Mike"
},
{
"id": "201",
"name": "abc xyz"
},
{
"id": "202",
"name": "abc befd"
},
{
"id": "210",
"name": "jki yuiu"
},
{
"id": "203",
"name": "asdfui uiuu"
},
{
"id": "204",
"name": "sfdhu uiu"
},
{
"id": "205",
"name": "asdfui uyu"
}
]
}
Using Underscore i want to filter the above data using sql like query on id.
for example if pass "2" the json should be filtered and return a new json which contain id starting with 2, If i pass 20 it should return new json with id starting with 20
similar to sql like query and then return n results matching,
correction: I want the data starting with id 2 or whatever parameter i pass i need data starting with it
Try this
function getResult(keyToFilter, valueStartsWith){
return _.filter(results, function(d){ return d[keyToFilter].startsWith(valueStartsWith); })
}
getResult("name", "asdfui");
[{
"id": "203",
"name": "asdfui uiuu"
},
{
"id": "205",
"name": "asdfui uyu"
}]
What about Array.prototype.filter and Array.prototype.slice? (underscore has similar functions but why to use them when it can be solved with plain JS)
function sqlLikeFilter(data, id, maxn) {
return data.result.filter(function(x) { return x.id == id; }).slice(0, maxn);
}
console.log(sqlLikeFilter(yourData, 125, 1));
Try this
function(id){
var result = _.filter(results, function(value) {
return value.id === id
})
return result;
}

Categories

Resources