Removing properties from JSON response - javascript

I have this JSON (as a string):
[{"product":{"id":"25","age":"35","name":"hp keyboard"},"quantity":1},
{"product":{"id":"9","age":"25","name":"lenovo hero"},"quantity":2}]
How can delete or remove all id & age properties (with their value) from the array of objects, so I can get new array out of it?

You seem to have an array with two JSON strings, but as you present them in your question they are not valid.
I'll assume your array is in fact like this -- run the snippet to see how many backslashes really need to be there:
let jsons = [
JSON.stringify({ product: { id: "25", age:"35", name: "hp keyboard" }, quantity: 1 }),
JSON.stringify({ product: { id: "9", age:"25", name: "lenovo hero" }, quantity: 2 })
];
console.log(jsons);
You should ask yourself why you stick with JSON, and do not just parse them, and then continue without JSON. But, given that you have JSON there, here is how you can remove the two said properties:
let jsons = [
JSON.stringify({ product: { id: "25", age:"35", name: "hp keyboard" }, quantity: 1 }),
JSON.stringify({ product: { id: "9", age:"25", name: "lenovo hero" }, quantity: 2 })
];
let jsons2 = jsons.map(json => {
let { product: { id, age, ...restProduct }, ...rest } = JSON.parse(json);
return JSON.stringify({ product: restProduct, ...rest });
});
console.log(jsons2);
Note how first the JSON is parsed, then a new object is created that lacks the two properties, and finally that is converted back to JSON again.
If you want to only keep some specific properties ("white list") in a flat (non-nested JSON, then proceed like this:
let jsons = [
JSON.stringify({ product: { id: "25", age:"35", name: "hp keyboard" }, quantity: 1 }),
JSON.stringify({ product: { id: "9", age:"25", name: "lenovo hero" }, quantity: 2 })
];
let jsons2 = jsons.map(json => {
let { product: { id, age }, quantity } = JSON.parse(json);
return JSON.stringify({ id, age, quantity });
});
console.log(jsons2);
In case your input is not an array (as hinted in your comments below), but a JSON string as a whole, then proceed as follows:
let json = JSON.stringify([
{ product: { id: "25", age:"35", name: "hp keyboard" }, quantity: 1 },
{ product: { id: "9", age:"25", name: "lenovo hero" }, quantity: 2 }
]);
let json2 = JSON.stringify(
JSON.parse(json).map(({ product: { id, age }, quantity }) =>
({ id, age, quantity })
)
);
console.log(json);

Just iterate over the array using Array.prototype.forEach and delete the unwanted properties:
const arr = [{
"product": {
"id": "25",
"age": "35",
"name": "hp keyboard"
},
"quantity": 1
},
{
"product": {
"id": "9",
"age": 25,
"name": "lenovo hero "
},
"quantity ": 2
}
]
const newArr = JSON.parse(JSON.stringify(arr)); // deep clone arr
newArr.forEach(function(arrEl) {
delete arrEl.product.id;
delete arrEl.product.age
});
console.log(arr); // old array unchanged
console.log(newArr); // new Array with deleted properties

Related

JS Object append and only add new value to the first object [duplicate]

This question already has answers here:
Array.push() if does not exist?
(30 answers)
Closed 11 months ago.
I have 2 objects, and I want to add a new key value pair to only the first match object of it's kind.
Obj1
[{
buyDate: "yesterday",
productId: "0001",
consumerId: "John",
price: 10
// add new key value pair here
},
{
buyDate: "today",
productId: "0001",
consumerId: "John",
price: 10
},
{
buyDate: "yesterday",
productId: "0002",
consumerId: "Doe",
price: 7
}]
Obj2
{
productId: "0001",
consumerId: "John",
quantity: 4
}
In Obj1, since the productId and the consumerId are the same, I want to add a new key value pair from Obj2 that has the same productId and consumerId to the first 0001 and John.
I got stuck from here.
let newObj2 = {};
if (Obj1) {
Obj1.forEach((e) => {
newObj2[e.consumerId] = e;
});
}
let newData = Obj1.map((e) => {
return {
...e,
quantity: Obj2[e.consumerId]?.quantity
? Obj2[e.consumerId]?.quantity
: 0,
};
});
Could anyone give me some help how to achieve that? Appreciate any kinda response.
Thanks before
edit: since it's a dummy data I wrote some mistake
Use Array.find to find the item in the array being searched like so:
const obj1 = [
{ buyDate: "yesterday", productId: "0001", consumerId: "John", price: 10 },
{ buyDate: "today", productId: "0001", consumerId: "John", price: 10 },
{ buyDate: "yesterday", productId: "0002", consumerId: "Doe", price: 7 }
];
const obj2 = {
productId: "0001", consumerId: "John", quantity: 4
};
let item = obj1.find(function(item) {
return item.productId === obj2.productId && item.consumerId === obj2.consumerId
});
if (item === undefined) {
// not found
} else {
item.quantity = obj2.quantity;
}
console.log(obj1);

Search objects for a given string

I have these objects
const data = [
{
id: 1,
recipient: "001",
assessment: "Apta",
score: "2",
ovarian: "E1",
},
{
id: 2,
recipient: "ABC2",
assessment: "Apta",
score: "2,5",
ovarian: "E1",
},
{
id: 3,
recipient: "003",
assessment: "Refugo",
score: "3",
ovarian: "E1",
},
{
id: 4,
recipient: "004",
assessment: "Apta",
score: "4",
ovarian: "E2",
},
];
And this is my code, which when it finds the correct string it returns me:
const searchAnimal = value => {
setInput(value);
JSON.parse(records).filter(item => {
if (item.recipient === value) {
setSearch([item]);
}
});
};
What would the logic be to return all object.recipients that start with 00? Would a regex maybe do it?
I think changing a little bit the logic would help:
let search = function (data, searchString) {
return data.filter((item) => {
return item.recipient.includes(searchString);
});
};
By doing so will give you the object you're searching for.
You can filter for the objects with a recipient that starts with 00 by using:
const array00Animals = data.filter((animal) => animal.recipient.substr(0, 2) === '00');
This will return the array of objects but only id's 1, 3 and 4 from your sample data.

Javascript compare two JSON arrays and return key of the unmatched value

I have two JSON arrays, would like to know the key which don't match. I don't need the value.
Example:
livetable: [
{ id: 1, name: "Sandra" },
{ id: 2, name: "John" },
],
backupTable: [
{ id: 1, name: "Sandra" },
{ id: 2, name: "Peter" },
],
I can get the key/value pair which is diffrent with this Lodash script:
difference = _.differenceWith(livetable,backupTable,_.isEqual)
But I would just need the key, in this example "name" for "id: 2" is not matching, so I would need to get the "name" key to new array/variable.
(Using VUE CLI)
EDIT: Added example of current code output.
var livetable = [{"id": 1, "name": "Sandra", "id": 2, "name": "John"}]
var backupTable = [{"id": 1, "name": "Sandra", "id": 2, "name": "Peter"}]
console.log(_.differenceWith(backupTable,livetable,_.isEqual))
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
This will output the key:value pair, but I would just need the key which is diffrent.
I think I understand what you're trying to do. There are some unknowns though, like what should happen if there is a missing record in the second data set?
This solution assumes each table of data has the same amount of records and the records have the same IDs.
// define data
const livetable = [
{ id: 1, name: "Sandra" },
{ id: 2, name: "John" }
]
const backupTable = [
{ id: 1, name: "Sandra" },
{ id: 2, name: "Peter" }
]
const getDifferentRecordsByID = (sourceRecords, compareRecords) => {
// simple utility function to return a record object matching by ID
const findComparisionRecord = id => compareRecords.find(compareRecord => compareRecord.id === id)
// using the utility function, we can filter out any mismatching records by comparing name
return sourceRecords
.filter(sourceRecord => sourceRecord.name !== findComparisionRecord(sourceRecord.id).name)
// then map over all the records and just pull out the ID
.map(record => record.id)
}
console.log(getDifferentRecordsByID(livetable, backupTable)) // [2]
Here is working VUE code for my problem.
Function returns [ "name" ], which is exactly what I need.
data() {
return {
livetable: [{ id: 1, name: "Sandra" },{ id: 2, name: "John" }],
backupTable: [{ id: 1, name: "Sandra" },{ id: 2, name: "Peter" }],
difColumns: null,
};
},
methods: {
test3() {
let resultArray = []
this.livetable.forEach((array1, index) => {
const array2 = this.backupTable[index];
resultArray.push(this._.reduce(array1, (result, value, key) => this._.isEqual(value, array2[key]) ? result : result.concat(key), []))
});
this.difColumns = resultArray[0]
}
},

Grouping array data according to a id

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>

Map value of an attribute in one object array to an attribute in another object array Javascript

I have two arrays of objects:
courses = [ { _id: 999, courseCode: "Eng1" },
{ _id: 777, courseCode: "Sci1" },
{ _id: 666, courseCode: "Eng2" },
{ _id: 888, courseCode: "Sci2" } ]
sectionCourses = [ { sectionCode: "1A", courseId: "999" },
{ sectionCode: "1A", courseId: "777" },
{ sectionCode: "2A", courseId: "666" },
{ sectionCode: "2A", courseId: "888" } ]
I want to filter the courses array in such a way that it contains only the courses that are not in a section.
For example if I select section with sectionCode: "2A", the courses array should only contain
courses = [ { _id: 999, courseCode: "Eng1" },
{ _id: 777, courseCode: "Sci1" },
{ _id: 888, courseCode: "Sci2" } ]
I tried to do this way:
courses = courses.filter(c => !(sectionCourses.includes(c._id)))
but I know this is incomplete because I can't figure out how to access courseId in sectionCourses.
Please help.
You can't use .includes() method to find the whole object by its _id, includes compares the whole objects and doesn't search for a specific property.
What you can do here is to get an array of courseIds to be ignored based on the sectionCode you provided, and then filter the courses that their _id doesn't exist in this array of ids:
function getCourses(catCode) {
var coursesIdstoIgnore = sectionCourses.filter(s => s.sectionCode === catCode).map(s => s.courseId);
return courses.filter(c => coursesIdstoIgnore.indexOf(c["_id"].toString()) == -1);
}
Demo:
var courses = [{
_id: 999,
courseCode: "Eng1"
},
{
_id: 777,
courseCode: "Sci1"
},
{
_id: 666,
courseCode: "Eng2"
},
{
_id: 888,
courseCode: "Sci2"
}
];
var sectionCourses = [{
sectionCode: "1A",
courseId: "999"
},
{
sectionCode: "1A",
courseId: "777"
},
{
sectionCode: "2A",
courseId: "666"
},
{
sectionCode: "2A",
courseId: "888"
}
];
function getCourses(catCode) {
var cousesIdstoIgnore = sectionCourses.filter(s => s.sectionCode === catCode).map(s => s.courseId);
console.log(cousesIdstoIgnore);
return courses.filter(c => cousesIdstoIgnore.indexOf(c["_id"].toString()) == -1);
}
var results = getCourses("2A");
console.log(results);
courses.filter(course => sectionCourses.find(section => +section.courseId === +course._id))
Note how i use the +operator before of the courseId and _id properties. this automatically turns a String typed number into a Number.
e.g
+"1" = 1
+1 = 1
This is very useful for slight comparison gotchas when using ===
Note Array.find() doesn't work with IE

Categories

Resources