This is the structure of my data. An array of shipments containing array of items
I need to have an array with entries for each shipment-item and I need to do this with javascript
[
{
"shipmentNumber":12345678,
"items":[
{
"productId":80000000000001,
"price":100,
"quantity":1
},
{
"productId":80000000000002,
"price":80,
"quantity":1
}
]
},
{
"shipmentNumber":89675645,
"items":[
{
"productId":80000000000003,
"price":100,
"quantity":1
}
]
}
]
This is what I want to achieve:
N.B.: The main array containing shipments has 5000+ elements
[
{
"shipmentNumber":12345678,
"items": {
"productId":80000000000001,
"price":100,
"quantity":1
}
},
{
"shipmentNumber":12345678,
"items":
{
"productId":80000000000002,
"price":80,
"quantity":1
}
},
{
"shipmentNumber":89675645,
"items":
{
"productId":80000000000003,
"price":100,
"quantity":1
}
}
]
A combination flatMap/map should do the trick:
result = a.flatMap(
s => s.items.map(
item => ({shipmentNumber: s.shipmentNumber, item})
))
You can use .map() to map the needed data in each nested array,and .flatMap() method to flatten the result arrays into the single array.
const shipments = [
{
"shipmentNumber":12345678,
"items":[
{
"productId":80000000000001,
"price":100,
"quantity":1
},
{
"productId":80000000000002,
"price":80,
"quantity":1
}
]
},
{
"shipmentNumber":89675645,
"items":[
{
"productId":80000000000003,
"price":100,
"quantity":1
}
]
}
];
const result = shipments.flatMap(shipment =>
shipment.items.map(item => ({
shipmentNumber: shipment.shipmentNumber,
item: item
}))
);
console.log(result);
Related
I have the below object, and want to remove the element("virAddrSeq": "345").
var state={
"todos": [
{
"accountNo": "50190000",
"name": "Sarkar",
"vpainfo": [
{
"virAddrSeq": "345"
},
{
"virAddrSeq": "34775"
}
]
}
]
}
I have tried the below way but getting all the records with out removing the element.
const newObj = Object.assign({}, state, {
todos: state.todos.filter(todoObj => (todoObj.vpainfo.filter(({virAddrSeq}) => (virAddrSeq != "345"))))
})
console.log(newObj)
var state = {
"todos": [{
"accountNo": "50190000",
"name": "Sarkar",
"vpainfo": [{
"virAddrSeq": "345"
},
{
"virAddrSeq": "34775"
}
]
}]
}
console.log(
state.todos.map(todo => ({...todo, vpainfo: todo.vpainfo.filter(({virAddrSeq}) => virAddrSeq!= 345)}))
)
var state = {
"todos": [{
"accountNo": "50190000",
"name": "Sarkar",
"vpainfo": [{
"virAddrSeq": "345"
},
{
"virAddrSeq": "34775"
}
]
}]
}
for (const s of state.todos) {
let findKey =s.vpainfo.find(x => x.virAddrSeq == '345')
let index = s.vpainfo.indexOf(findKey)
if(findKey && index > -1) s.vpainfo.splice(index,1)
}
console.log(state)
I have a jSOn with two arrays. I would like to merge all items of both arrays into a single array. Is there a jSOn path syntax i could use to give the desired output?
I have this:
[
"SomeArray",
{
"Branch1": {
"Branch2": {
"Branch3": {
"Array1": [
"Item1InArray1",
"Item2InArray1"
],
"Array2": [
"Item1InArray2",
"Item2InArray2"
]
}
}
}
}
]
And want this output: Its essentially two paths: [1].Branch1.Branch2.Branch3.Array1 and [1].Branch1.Branch2.Branch3.Array2
[
"Item1InArray1",
"Item2InArray1",
"Item1InArray2",
"Item2InArray2"
]
This simple example shows how you can achieve this having a full string-based path.
const arr = [
{
"Branch1": {
"Branch2": {
"Branch3": {
"Array1": [
"Item1InArray1",
"Item2InArray1"
],
"Array2": [
"Item1InArray2",
"Item2InArray2"
]
}
}
}
}
];
const paths = ["0.Branch1.Branch2.Branch3.Array1", "0.Branch1.Branch2.Branch3.Array2"];
const result = paths.map(path => path.split(".").reduce((unique, value) => unique[value], arr)).flat()
console.log(result)
You could simply get all nested arrays.
const
flat = item => item && typeof item === 'object'
? Array.isArray(item)
? item
: Object.values(item).flatMap(flat)
: [],
data = ["SomeArray", { Branch1: { Branch2: { Branch3: { Array1: ["Item1InArray1", "Item2InArray1"], Array2: ["Item1InArray2", "Item2InArray2"] } } } }],
items = data.flatMap(flat);
console.log(items);
{
"Branch1": {
"Branch2": {
"Branch3": {
"Array1": [
"Item1InArray1",
"Item2InArray1"
],
"Array2": [
"Item1InArray2",
"Item2InArray2"
]
}
}
}
}
]
let newArray = array1.reduce((main, curr)=> main.concat(curr.Branch1.Branch2.Array1, curr.Branch1.Branch2.Array1),[])
I have a json array with different key values and need to add a ServerUrl to the beginning of all node values using a loop without writing multiple statements to do that by using javascript:
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
The expected result must be:
"Urls": [
{ "getCar": "http://192.168.1.1:3000/getAllCars" },
{ "getPerson": "http://192.168.1.1:3000/getAllPersons" },
{ "getBook": "http://192.168.1.1:3000/getAllBooks" }
],
Any advice would be appreciated.
You can use map to map your objects to new objects. Those objects have a single property, which you can get with Object.keys. The new object can get that same property name using the computed property name feature:
var obj = {
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
};
var urls = obj.Urls.map(o => Object.keys(o).map(k => ({ [k]: obj.ServerUrl + o[k] }))[0]);
console.log(urls);
const jsonVal = {
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
}
const result = jsonVal.Urls.map(val =>
Object.keys(val).reduce((resultObj, endpointKey) => {
resultObj[endpointKey] = `${jsonVal.ServerUrl}${val[endpointKey]}`;
return resultObj;
}, {})
);
Try (where your data are in d)
d.Urls.forEach( (x,i,a,k=Object.keys(x)[0]) => x[k] = d.ServerUrl + x[k]);
let d = {
"Urls": [
{ "getCar": "/GetAllGroupCustomers" },
{ "getPerson": "/getAllItems" },
{ "getBook": "/GetAllCustomers" }
],
"ServerUrl": "http://192.168.1.1:3000"
}
d.Urls.forEach( (x,i,a,k=Object.keys(x)[0]) => x[k] = d.ServerUrl + x[k]);
console.log(d);
A version that modifies your own object
var obj = {
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
};
obj.Urls.forEach(o => o[Object.keys(o)[0]] = `${obj.ServerUrl}${o[Object.keys(o)[0]]}`);
console.log(obj);
I have product structure as shown below:
product = {
"name":"MyXam",
"layers":[
{
"countries":[
{
"countryId":"1",
"countryName":"ABC"
},
{
"countryId":"2",
"countryName":"XYZ"
},
{
"countryId":"3",
"countryName":"PQR"
}
]
},
{
"countries":[
{
"countryId":"5",
"countryName":"LMN"
},
{
"countryId":"3",
"countryName":"PQR"
}
]
}
]
}
And selected countries:
selCountries = [
{
"countryId":"1"
},
{
"countryId":"3"
}
]
Now I want to filter the product in such a way that it should contain countries only that are in selCountries.
The final product should be:
{
"name":"MyXam",
"layers":[
{
"countries":[
{
"countryId":"1",
"countryName":"ABC"
},
{
"countryId":"3",
"countryName":"PQR"
}
]
},
{
"countries":[
{
"countryId":"3",
"countryName":"PQR"
}
]
}
]
}
I have tried the following using lodash but is not working:
_.filter(product.layers, _.flow(
_.property('countries'),
_.partialRight(_.some, selCountries)
));
As the product comes dynamically in my application. In some cases there is a possibility that some of the layers may have not countries. So the solution should handle this case also and should not break with undefined error.
Can any on help me, where I am going wrong?
You should not need lodash for that. Just filter based on ID. If for all layers, map/forEach on the layers and filter the countries.
const product = {
"name":"MyXam",
"layers":[
{
"countries":[
{
"countryId":"1",
"countryName":"ABC"
},
{
"countryId":"2",
"countryName":"XYZ"
},
{
"countryId":"3",
"countryName":"PQR"
}
]
}
]
}
const selCountries = [
{
"countryId":"1"
},
{
"countryId":"3"
}
];
const indices = selCountries.map(e => e.countryId); // Just IDs plz.
product.layers.forEach(layer => {
if (layer.countries == null)
return;
layer.countries = layer.countries.filter(e =>
indices.some(i => i == e.countryId)
);
});
console.log(product);
My answer's similar to 31piy's in that I extract out the ids from selCountries first, and then rebuild the object with the filtered results. It also checks whether there are countries in the layers array as per your recent comment.
product = {"name":"MyXam","layers":[{"countries":[{"countryId":"1","countryName":"ABC"},{"countryId":"2","countryName":"XYZ"},{"countryId":"3","countryName":"PQR"}]},{"countries":[{"countryId":"5","countryName":"LMN"},{"countryId":"3","countryName":"PQR"}]}]}
const selCountries=[{"countryId":"1"},{"countryId":"3"}];
if (product.layers.length) {
const selCountriesArr = selCountries.map(el => el.countryId);
const newLayers = product.layers.map(obj => {
const countries = obj.countries.filter(el => selCountriesArr.includes(el.countryId));
return { countries };
});
const filteredProduct = { ...product, layers: newLayers };
console.log(filteredProduct);
}
You can create a temporary array with the IDs of countries selected, and then filter the countries based on it. Note that it modifies the original object in-place.
let product = {
"name": "MyXam",
"layers": [{
"countries": [{
"countryId": "1",
"countryName": "ABC"
},
{
"countryId": "2",
"countryName": "XYZ"
},
{
"countryId": "3",
"countryName": "PQR"
}
]
}]
};
let selCountries = [{
"countryId": "1"
},
{
"countryId": "3"
}
];
// Extract the IDs
let selCountryIds = _.map(selCountries, 'countryId');
// Filter the countries based on IDs
product.layers[0].countries = _.filter(product.layers[0].countries, country => {
return _.includes(selCountryIds, country.countryId);
});
console.log(product);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Instead of using lodash, you can make use of Array.map and Array.filter to iterate through the array and filter the product as per the selected countries.
var product = {
"name":"MyXam",
"layers":[
{
"countries":[
{
"countryId":"1",
"countryName":"ABC"
},
{
"countryId":"2",
"countryName":"XYZ"
},
{
"countryId":"3",
"countryName":"PQR"
}
]
}
]
}
var selCountries = [
{
"countryId":"1"
},
{
"countryId":"3"
}
];
product.layers = product.layers.map(function (layer) {
return layer.countries.filter(function (country) {
return selCountries.some(function(selCountry) {
return selCountry.countryId === country.countryId;
});
});
});
console.log(product);
this is the array variable
let packageitems=
[
{
"packageid":1,
"items":[
{
"itemid":"1",
"name":"abc"
},
{
"itemid":"2",
"name":"cdr"
}
]
},
{
"packageid":2,
"items":[
{
"itemid":"1",
"name":"abc"
},
{
"itemid":"2",
"name":"xyz"
}
]
}
]
in angular typescript i am having one function:
updatePackageitem(newitem){
let objIndex = this.packageitems.findIndex(obj => obj.packageid==newitem.packageid);
Object.assign(this.packageitems[objIndex] , newitem);
}
newitem json is similar just the items array is different
when i assign using Object.assign the newitem array elements get copies to all rest json of this.packageitems even after getting the objIndex right
newitem =
{
"packageid":2,
"items":[
{
"itemid":"1",
"name":"def"
},
{
"itemid":"2",
"name":"pqr"
}
]
}