This question already has answers here:
Filtering array of objects with arrays based on nested value
(8 answers)
Closed last month.
I need to remove one item from nested object array by filtering key value
sample json
[
{
"featureID": "e0152c71-657f-4bc2-b7f5-77e4d5a2a5a0",
"feature": "TestTwo",
"type": "TestTwo",
"rules": [
{
"ruleId": "89919182-feb1-402c-b9ad-03ae62586f84",
"ruleName": "Machine Guarding",
"featureName": "TestTwo",
"parameters": [
]
},
{
"ruleId": "e5361f7f-d8ae-424d-b781-a01987111181",
"ruleName": "Eye&Face Protection",
"featureName": "TestTwo",
"parameters": [
]
},
]
},
{
"featureID": "67d6e1bf-3919-4dcc-b636-236ab41d431b",
"feature": "TestThree",
"type": "TestThree",
"rules": [
{
"ruleId": "4e00e08e-6a34-47cf-9012-0800bc0063f2",
"ruleName": "Maximum People",
"featureName": "TestThree",
"parameters": [
]
},
{
"ruleId": "a9ab3ce2-e69c-4c0c-b561-1107baed1e68",
"ruleName": "Redzone",
"featureName": "TestThree",
"parameters": [
]
}
]
},
]
In above JSON, I need to remove an item from "rules" array by "ruleId" property.
i.e : remove "ruleName":"Machine Guarding" item by that ruleId property.
I tried below
deleteItems(argId){
this.done.find((items,d)=>items.feature == argID.featureName).rules.filter((int,ind)=>int.ruleId == argID.ruleId)
}
The above function passes the respective "ruleId" property.
const data=[{featureID:"e0152c71-657f-4bc2-b7f5-77e4d5a2a5a0",feature:"TestTwo",type:"TestTwo",rules:[{ruleId:"89919182-feb1-402c-b9ad-03ae62586f84",ruleName:"Machine Guarding",featureName:"TestTwo",parameters:[]},{ruleId:"e5361f7f-d8ae-424d-b781-a01987111181",ruleName:"Eye&Face Protection",featureName:"TestTwo",parameters:[]}]},{featureID:"67d6e1bf-3919-4dcc-b636-236ab41d431b",feature:"TestThree",type:"TestThree",rules:[{ruleId:"4e00e08e-6a34-47cf-9012-0800bc0063f2",ruleName:"Maximum People",featureName:"TestThree",parameters:[]},{ruleId:"a9ab3ce2-e69c-4c0c-b561-1107baed1e68",ruleName:"Redzone",featureName:"TestThree",parameters:[]}]}];
const deleteItems = (ruleIdToFilter) => {
return data.map((item) => {
item.rules = item.rules.filter((rule) => ruleIdToFilter != rule.ruleId);
return item;
});
};
let response = deleteItems("89919182-feb1-402c-b9ad-03ae62586f84");
console.log(response);
Related
This question already has answers here:
How to remove all duplicates from an array of objects?
(77 answers)
Closed 4 months ago.
If the 'id' key is duplicated among the objects in the array, how to delete the object
I tried using filter, map, and set, but it doesn't work.
It's not a one-dimensional array, so I don't know how to do it.
as-is
"category": {
"key": 1,
"order": 1,
"list": [
{
"id": "12345",
...
},
{
"id": "12345",
...
},
{
"id": "67890",
...
},
]
}
to-be
"category": {
"key": 1,
"order": 1,
"list": [
{
"id": "12345",
...
},
{
"id": "67890",
...
},
]
}
We iterate over that list using reduce function, then we checked whether the key we are accessing is visited or not with keys parameter of reduce method, and if it's not visited then we just push that object to a filtered array and returning keys array to keep it updated.
const data = {
"category": {
"key": 1,
"order": 1,
"list": [{
"id": "12345"
},
{
"id": "12345"
},
{
"id": "67890"
},
]
}
}
let filtered = [];
data.category.list.reduce((keys, currentObject) => {
if (!keys.includes(currentObject.id)) { //checking if current oject id is present in keys or not
// if not present than we will just push that object in
keys.push(currentObject.id);
//getting filttered object
filtered.push(currentObject);
}
return keys; //returning keys to update it
}, [])
data.category.list = filtered; //updating list
console.log(data);
A solution based on #Nick's comment
let data ={
"category": {
"key": 1,
"order": 1,
"list": [
{
"id": "12345"
},
{
"id": "12345"
},
{
"id": "67890"
},
]
}
}
let uniq = data.category.list.filter((o,i,a) => a.findIndex(o2 => o2.id == o.id) == i)
data.category.list = uniq
console.log(data)
You can use a set to track if id
const category = [{
"category": {
"key": 1,
"order": 1,
"list": [{
"id": "12345",
},
{
"id": "12345",
},
{
"id": "67890",
},
]
}
}]
const z = category.map(elem => {
const set = new Set()
return {
...elem,
category: {
...elem.category,
list: elem.category.list.reduce((acc, curr) => {
if (!set.has(curr.id)) {
set.add(curr.id);
acc.push(curr)
}
return acc;
}, [])
}
}
});
console.log(z)
I have an object
{
"input":{
"id": "7879",
"inputType": "9876",
"streamName": "870"
},
"transformation":{
"id": "7",
"dependencies": [
"8i"
],
"dropColumns": "hkj",
"processor": "hgf"
},
"output": {
"id": "v",
"saveMode": "uyt",
"dependentIds": [
"h"
],
"outPartition":[
"hg"
]
}
}
Basically every value leaving the key I have to put it in an array. So input, transformation, output values(which are objects) should be placed inside array.
Expected Output:
{
"input": [
{
"id": "7879",
"inputType": "9876",
"streamName": "870"
}
],
"transformation":[
{
"id": "7",
"dependencies": [
"8i"
],
"dropColumns": "hkj",
"processor": "hgf"
}
],
"output":[
{
"id": "v",
"saveMode": "uyt",
"dependentIds": [
"h"
],
"outPartition":[
"hg"
]
}
]
}
I tried iterating using the for in loop but was not able to achieve the expected output how should I place the values(object) inside array
var arr = [];
for(key in obj){
arr.push(Object.assign(obj[key],{name: key}))
}
You mean this (although not sure why you would need this)?
const input = {
"input":{
"id": "7879",
"inputType": "9876",
"streamName": "870"
},
"transformation":{
"id": "7",
"dependencies": [
"8i"
],
"dropColumns": "hkj",
"processor": "hgf"
},
"output": {
"id": "v",
"saveMode": "uyt",
"dependentIds": [
"h"
],
"outPartition":[
"hg"
]
}
}
Object.keys(input).forEach(key => input[key] = [input[key]] )
console.log(input)
According to the output of the object you provided, a simple implementation of looping the elements and creating the keys as arrays can be:
for(key in obj){
obj[key] = [obj[key]];
}
You could rebuild it using the reduce function if you want to do it immutable:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.
More info see: MDN Webdocs - reduce()
const data = {
"input":{
"id": "7879",
"inputType": "9876",
"streamName": "870"
},
"transformation":{
"id": "7",
"dependencies": ["8i"],
"dropColumns": "hkj",
"processor": "hgf"
},
"output": {
"id": "v",
"saveMode": "uyt",
"dependentIds": ["h"],
"outPartition":["hg"]
}
};
const customFormat = (data) => Object.keys(data).reduce((object, key) => {
object[key] = [data[key]];
return object
}, {});
console.log(customFormat(data));
Here I have to get value of file_info, I tried doing it using array.includes and array.find(), but got undefined.
My confusion here is related to, under 'facts', the first value is "==", then it has array of values associated to it. I could not figure out to find the values inside that nested object.
I even tried array.find(facts).contains(fileinfo) that did not work as well.
How can I solve this ??
"data": [
{
"task-id": "126e7267",
"type": "A",
"output": {...}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
},
....
]
}
},
{
"task-id": "5f557eac",
"type": "C",
....
},
],
I have tried to validate your json string. It seems to be invalid. For answering this question , i would assume below string to be your json :
{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}
I had tried to figure out a repetative pattern in your json but since "#value" tag is seen inside only one "facts" object below code should help you getting started . For given json , below code prints the value of "file_info"(Here , i'am assuming that "file_info" should be followed by a colon(:) i.e. "a0s5b2e6e739" is the value you are looking for) :
var jsonStr = '{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}';
var jsonObj = JSON.parse(jsonStr);
//If there is a repetative pattern , you can replace this hard coding with your pattern.
var objArray = jsonObj["data"][1]["output"]["facts"][0]["=="][1]["#value"]["facts"];
console.log(objArray);
if(objArray && objArray.length >0){
for(let i =0;i<objArray.length;i++){
if(objArray[i] && objArray[i]["=="] && objArray[i]["=="].length > 0 && objArray[i]["=="][0]["file_info"]){
//here "file_info" is fetched
console.log('here ',objArray[i]["=="][0]["file_info"]);
}
}
}
Hope above code helps you to get started.
You can map and filter the object/array to get the result if the format is fixed. Here, I am writing to a Map and retrieving the property I need at the very end.
let data = [
{
"task-id": "126e7267",
"type": "A",
"output": {}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
}
]
}
},
{
"task-id": "5f557eac",
"type": "C",
"output": {}
}
]
const map = new Map()
const facts = data
.map(d => d.output)
.filter(o => o.hasOwnProperty('facts'))
.map(d => d.facts)
.map(i => i[0]["=="][1])
.map(d => d["#value"].facts)
const item = facts.forEach(o => o.forEach(i => map.set(i["=="][0], i["=="][1])))
console.log(map.get("file_info"))
Is there any plugin that allow to dynamically build following data structure in plain JavaScript object or JSON?
This is the structure I would like to implement:
Check my plunker (https://plnkr.co/edit/1eWjXLPumuOMhv8BjaNw?p=preview)
{
"name": "Select0",
"id": "select0",
"values": [
"Option1",
"Option2"
],
"dependent": {
"name": "Select1",
"id": "select1",
"values": {
"Option1": [
"Option11",
"Option12"
],
"Option2": [
"Option21",
"Option22"
]
},
"dependent": {
"name": "Select2",
"id": "select2",
"values": {
"Option1": {
"Option11": [
"Option111",
"Option112"
],
"Option12": [
"Option121",
"Option122"
]
},
"Option2": {
"Option21": [
"Option211",
"Option212"
],
"Option22": [
"Option221",
"Option222"
]
}
},
"dependent": []
}
}
}
Note that you can set values on properties on an object and then print it as a JSON.
var obj = {};
object.name = "Select0";
// Set more properities.
// Stringify object to JSON format looking as the one in the question.
var json = JSON.stringify(obj, null, 2);
// Verify by printing on the screen.
console.log(json);
Here is the my first JSON Array format...
[
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
]
and here is another JSON Array Format
[
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
]
The above mentioned Two JSON Arrays, i need to compare each one with Id and need to format a new JSON Array with caption and value using javascript.
[
[
{
"caption" : "caption1",
"value":"value11"
},
{
"caption" : "caption2",
"value":"value12"
},
{
"caption" : "caption3",
"value":"value13"
}
],
[
{
"caption" : "caption1",
"value":"value21"
},
{
"caption" : "caption2",
"value":"value22"
},
{
"caption" : "caption3",
"value":"value23"
}
]
]
Please help me out.
You can do it in many ways. Below I show two variants:
Option 1: Pure JavaScript
In this example the program preindex first array for faster access to it data, and then loops over second array with map() function to create new array of arrays:
// Create index version of first array
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
// Loop over array of arrays
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
}
});
Option 2: Using special SQL library (Alasql)
Here, you can JOIN to arrays automatically with special SQL statement:
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] \
FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
You can try these variants in working snippet below or play with it in jsFiddle.
(Disclaimer: I am the author of Alasql)
var arr1 = [
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
];
var arr2 = [
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
];
// JavaScript version
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
});
});
document.getElementById("res1").textContent = JSON.stringify(res1);
// Alasql version
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
document.getElementById("res2").textContent = JSON.stringify(res2);
<script src="http://alasql.org/console/alasql.min.js"></script>
<p>Varian 1: JavaScript</p>
<div id="res1"></div>
<p>Variant 2: Alasql</p>
<div id="res2"></div>