Hy, My Question is how we can map an array in react js in which the array has key-value pairs but these key values are dynamically added to the array . I mean I don't know what next key-value pair would come in an array.
example below
var array = [{ name: "kamran", age: 25 }, { dev: "kamran", hellow: "kamran" }, { "unknown key will be add dynamically": "unknown value to that key will be add dynamically" }];
for (var i = 0; i < array.length; i++) {
console.log(tifOptions[i]);
}
I want to show it on the table with keys and values using the map function. but the situation is data is coming from a rest API every time it gives me a different array of objects how could I show it will key and value I need to add to the project. because I don't know what key and value will come in the next API request
like below
first request from same API
[
{
'name':"kamran",
'age':25,
},
{
'dev':"js",
'db':"mongo",
},
];
second request from same API
[
{
'name':"kamran",
'age':25,
},
{
'dev':"js",
'db':"mongo",
},
{
'job':"student",
"salary":20000,
}
];
third request from same API
[
{
'name':"kamran",
'age':25,
},
{
'dev':"js",
'db':"mongo",
},
{
'job':"student",
"salary":20000,
},
{
' unknown key will be added':"unknown value will be added",
' unknown key will be added':"unknown value will be added",
}
];
and it goes on every time different key values how could I show this type of data on table with keys and value bcz I don't know in the next request what key value paire would come.
From my understanding of your question, you are going to do something with the key & value pairs coming from the API.
var array = [{ name: "kamran", age: 25 }, { dev: "kamran", hellow: "kamran" }, { "unknown key will be add dynamically": "unknown value to that key will be add dynamically" }];
array.map(item => {
var keys = Object.keys(item);
var obj= {};
keys.forEach(key => {
console.log("key : " ,key, "value : ", item[key])
// do some logic here
obj[key] = item[key];
})
return obj;
}))}
Live link here : https://codesandbox.io/s/youthful-lewin-pgyu8u?file=/src/App.js
I think the answer pretty obvious if you do some googling
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
The function simply let you map a new array base on your base array no matter what element is in it
Related
This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
Closed 2 years ago.
I have a file with 1000s of json rows like below. Im having difficulties locating a specific key in the array.
example json:
{"connection":"98374"
,"db":"8",
,"timestamp":"159905411631"
,"event":"DataCatch"
,"data":[{"key":"ruleid","value":"111"}
,{"key":"responseid","value":"155-response-4"}
,{"key":"responsetype","value":"Capture"}
,{"key":"reason","value":"ClientVisit"}
,{"key":"subreason","value":""}
,{"key":"score","value":"0.00"}
,{"key":"comment","value":""}]
}
I need to be able to find the "reason" key in the "data" array and replace the "value" with "test". The "data" array doesn't always appear on every json row, only when the "event" "dataCatch" is present.
I can parse it into a variable but I can only call the "data" array as a whole. Any ideas how to target specific values in an array?
Having a little trouble with this in Typescript.
There are any number of ways to go about this, but here's one.
First, parse your JSON into an array of objects.
Each element of the array will then look something like this:
{
connection: '98374',
db: '8',
timestamp: '159905411631'
event: 'DataCatch',
data: [
{ key: 'ruleid', value: '111' },
{ key: 'responseid', value: '155-response-4' },
{ key: 'responsetype', value: 'Capture' },
{ key: 'reason', value: 'ClientVisit' },
{ key: 'subreason', value: '' },
{ key: 'score', value: '0.00' },
{ key: 'comment', value: '' },
],
}
Let's call our array of objects allData, so we can refer to it later.
Now we can begin our "surgery".
We'll work from the inside-out, first looking at what needs to be done to a specific entry in an element's data array.
Here's a function that will do just what we need:
function updateReason(entry) {
if (entry.key === 'reason') {
return { ...entry, value: 'test' };
} else {
return entry;
}
}
This function checks if the provided entry has a key with a value of 'reason', and -- if so -- returns a new entry that is identical to the provided one except its value is 'test'.
How can we use this to update an entire data array (in an entry that has data, that is)?
We simply delegate the work to our dear friend map:
function updateData(data) {
// or simply `data.map(updateEntry);`
return data.map(entry => updateEntry(entry));
}
We're slowly working our way "outwards".
What about updating an entire entry in our big allData array (which may or may not contain data)?
// I've called such an entry a "collection", because I already used the name
// "entry" above :(
// A "collection" is just an entry in the big `allData` array.
function updateCollection(collection) {
if (collection.event === 'DataCatch') {
return {
...collection, // Leave everything else the way it is
data: updateData(collection.data), // But update the `data` array
};
} else {
return collection;
}
}
So close.
The last thing we need to do is apply this transformation to every element of our parsed allData array:
// or `allData.map(updateCollection);`
const updatedData = allData.map(collection => updateCollection(collection));
Also:
Q: Wouldn't it be cheaper to mutate the entry?
A: It would be cheaper, but not that much cheaper, due to a large amount of "structural sharing" that occurs here. I would recommend this approach unless you either need to mutate your input for some reason, or performance requirements demand it.
You need to map over the data key in your data variable like this.
data.data = data.data.map((item) => {
if (item.key === "reason") {
item.value = "test";
}
return item;
});
the data key is an array of values, so you need to loop through it and compare the value of the key property to the value you are looking for, if it matches then you can update the value property
https://codesandbox.io/s/angry-shirley-1gh83?file=/src/index.ts:666-782
This question already has answers here:
Group array of object nesting some of the keys with specific names
(2 answers)
Closed 2 years ago.
I have an array and i want to filter this array by Country and Service
i did the filter by Country but i want also do the same thing by service
this the array :
[
{
"Country":"CHINA",
"details":"None",
"Service":"BUSINESS",
},
{
"Country":"USA",
"details":"Bus-Trip",
"Service":"BUSINESS",
},
{
"Country":"USA",
"details":"Comm-Trip",
"Service":"COMMUNICATION",
},
];
I was able to do that by this code
let objectData = Data.reduce(function (acc,cur) {
if (!acc[cur.Country])
acc[cur.Country] = { data : []};
acc[cur.Country].data.push(cur)
return acc;
},
{} );
the code above allowed me to filter only by country and it's work but i want to do this same
thing by country and service BOTH and i want the result like this :
[
{
Country :"CHINA",
Service : [
{"details":"None",}
]
},
{
Country :"USA" ,
Service : [
{"details":"Bus-Trip"},
{"details":"Comm-Trip"}
]
},
]
Some slight modifications to your new object for each country so it reflects what you want and then use Object.values() to get the expected results array
let grouped = Data.reduce(function (acc,{Country, ...rest}) {
acc[Country] = acc[Country] || {Country, Services : []};
acc[Country].Services.push(rest)
return acc;
},{} );
const res = Object.values(grouped)
console.log(res)
<script>
const Data=[{Country:"CHINA",details:"None",Service:"BUSINESS"},{Country:"USA",details:"Bus-Trip",Service:"BUSINESS"},{Country:"USA",details:"Comm-Trip",Service:"COMMUNICATION"}];
</script>
You can try this code.
objectData = Data.reduce(function (acc,cur) {
if (!acc[cur.Country])
acc[cur.Country] = [];
acc[cur.Country].push({details: cur.details});
return acc;
}, {} );
objectData = Object.keys(objectData).map(key => ({
Country: key,
Service: objectData[key]
}));
You first need to modify the reduce code a bit, to contain details data only because you want to strip services.
At this moment, country will be key, so you need one more step to convert objectData to the desired format.
Object.keys(objectData) returns all countries list without duplication, so the second part finally builds the format you require.
So I am pretty new when it comes to Javascript and it is as simple as read a json list with a value of:
{
"URL": [{
"https://testing.com/en/p/-12332423/": "999"
}, {
"https://testing.com/en/p/-123456/": "123"
},
{
"https://testing.com/en/p/-456436346/": "422"
}
]
}
What I would like to do is to have both the URL and the amount of numbers etc
"https://testing.com/en/p/-12332423/" and "999"
and I would like to for loop so it runs each "site" one by one so the first loop should be
"https://testing.com/en/p/-12332423/" and "999"
second loop should be:
"https://testing.com/en/p/-123456/" and "123"
and so on depending on whats inside the json basically.
So my question is how am I able to loop it so I can use those values for each loop?
As Adam Orlov pointed out in the coment, Object.entries() can be very useful here.
const URLobj = {
"URL": [{
"https://testing.com/en/p/-12332423/": "999"
}, {
"https://testing.com/en/p/-123456/": "123"
},
{
"https://testing.com/en/p/-456436346/": "422"
}
]
};
URLobj.URL.forEach(ob => {
console.log('ob', ob);
const entries = Object.entries(ob)[0]; // 0 just means the first key-value pair, but because each object has only one we can just use the first one
const url = entries[0];
const number = entries[1];
console.log('url', url);
console.log('number', number);
})
You mean something like this using Object.entries
const data = {
"URL": [
{"https://testing.com/en/p/-12332423/": "999"},
{"https://testing.com/en/p/-123456/": "123"},
{"https://testing.com/en/p/-456436346/": "422"}
]
}
data.URL.forEach(obj => { // loop
const [url, num] = Object.entries(obj)[0]; // grab the key and value from each entry - note the [0]
console.log("Url",url,"Number", num); // do something with them
})
let's call your object o1 for simplicity. So you can really go to town with this link - https://zellwk.com/blog/looping-through-js-objects/
or you can just use this code :
for(var i = 0; i < o1.URL.length; i++) {
//each entry
var site = Object.keys(URL[i]) [0];
var value = Object.values(URL[i]) [0];
// ... do whatever
}
don't forget each member of the array is an object (key : value) in its own right
You can extract the keys and their values into another object array using map
Then use the for loop on the newly created array. You can use this method on any object to separate their keys and values into another object array.
const data = {
"URL": [{
"https://testing.com/en/p/-12332423/": "999"
}, {
"https://testing.com/en/p/-123456/": "123"
},
{
"https://testing.com/en/p/-456436346/": "422"
}
]
}
var extracted = data.URL.map(e => ({
url: Object.keys(e)[0],
number: Object.values(e)[0]
}))
extracted.forEach((e) => console.log(e))
So I'm building a basic facet search in React using data from an API, but I'm struggling with the adding & removing of values from the payload sent back to the server. The payload object can contain Arrays, Objects & Strings. So say I have a payload structure like the following:
payload = {
search_query: ""
topic: [],
genre: [],
rating: "",
type: {}
}
Using deepmerge I'm able to pass multiple values back to the API which is working fine, so an example payload would be...
payload = {
search_query: "Luther"
topic: ["9832748273", "4823794872394"],
genre: ["3827487483", "3287483274873"],
rating: "18",
type: {
args: {
when: "today",
min: 15
},
name: "spot"
}
}
So far so good, I get the expected results back. Now I have a toggle on the facet to remove it from the payload, which sends back the value to a function to remove from the payload. For example:
Clear Search, value to remove = "Luther"
Toggle of topic, value to remove = "9832748273"
Toggle of genre, value to remove = "3827487483"
Toggle of rating, value to remove = "18"
Toggle of type, value to remove = { args: { when: "today", min: 15}, name: "spot"}
Search & Rating would return empty strings, topic & genre would remove items from the arrays and type would return an empty object.
This works for removing the array values but feels dirty and I want a clean way to handle all types!
const removeObjValue = (obj, filterValue) => {
Object.entries(obj).forEach(([key, value]) => {
Object.entries(value).forEach(([subKey, subValue]) => {
if(subvalue === filterValue) {
if(Array.isArray(value)) {
const index = value.indexOf(subvalue);
if (index > -1) {
value.splice(index, 1);
}
}
}
});
});
return obj;
}
I just use delete keyword to remove object attributes, like this
if (payload[key]) {
if (payload[key] instanceof Array) {
var idx = payload[key].indexOf(value);
if (idx > -1) payload[key].splice(idx, 1);
} else {
delete payload[key];
}
}
code example
I want to compare the data.examples array object name.value property value with wcObject.notCoveredList key, If the key matches I want to push all matched values of wcObject to an array inorder to display in UI. If the key doesn't match, I want the name.desc property value of data.examples array object to be pushed by removing the not covered text at the end.
data = {
examples : [
{
name: {
value:"someOne",
desc: "some random word not covered"
},
type: {
value:"General",
desc:"General"
}
}, {
name: {
value:"secondOne",
desc: "second on in the queue not covered"
},
type: {
value:"General",
desc:"General"
}
}, {
name: {
value:"thirdOne",
desc: "third one from the last not covered"
},
type: {
value:"General",
desc:"General"
}
}
]
}
wcObject = {
notCoveredList : [
{ someOne: "anyone can start " },
{ secondOne: "second One cannot start" },
{ thirdOne: "third One can be allowed" }
]
}
So, this code:
Builds up a filter object. We grab all the keys of
wcObject.notCoveredList, and make them keys on a single object (with
an undefined value), so that we can look up those keys with a single
hasOwnProperty() call instead of iterating over an array when we need to filter.
Maps every member of the data.examples array to either its own name.desc property or [stripped of ' not covered'] name.value property.
.
wcNotCoveredKeys = wcObject.notCoveredList.reduce((memo, item) => {
// value is empty for all, we only care about keys.
memo[Object.keys(item)[0]] = undefined;
return memo;
}, {})
// having built up our lookup table of those not covered, we continue:
forUI = data.examples.map(example => {
if (wcNotCoveredKeys.hasOwnProperty(example.name.value)) {
return example.name.value;
}
else {
notCoveredString = example.name.desc;
cutOutIndex = notCoveredString.indexOf(' not covered');
return notCoveredString.slice(0, cutOutIndex)
}
});
(updated to integrate string slicing)
Just to be clear: if you removed the second item from wcObject.notCoveredList, then the output you'd get in forUI (given the example data structures/values you provided) would be
["someOne", "second on in the queue", "thirdOne"]