Convert to Object and Adding property to object of array - javascript

I want to make filter by date with this object of array
const mapDateRange = () => {for (let elem in catchData) {
let x = {startDate:catchData[elem][0],finishDate:catchData[elem][1]};
return x;
}};
but its only catch one object of array
this is latest data has processing
const data = {
["01-08-2019", "08-08-2019"],
["08-08-2019", "15-08-2019"],
["15-08-2019", "22-08-2019"],
["22-08-2019", "29-08-2019"]
};
this is what i expected
const data = [
{
startDate:"01-08-2019", finisDate:"08-08-2019"
},
{
startDate:"08-08-2019", finisDate:"15-08-2019"
},
{
startDate:"15-08-2019", finisDate:"22-08-2019"
},
{
startDate:"22-08-2019", finisDate:"29-08-2019"
}
];

So there are a few problems in the code you wrote:
Your data started as an object ({}), but its built as an array, so I corrected that.
Your function mapDateRange uses catchData but it does not exist anywhere so I made the function except an argument, which will be the catchData.
Most important: You returned x which is only 1 item in the array of data. So I created an empty array and pushed x values to the array.
const data = [
["01-08-2019", "08-08-2019"],
["08-08-2019", "15-08-2019"],
["15-08-2019", "22-08-2019"],
["22-08-2019", "29-08-2019"]
];
const mapDateRange = (catchData) => {
let new_data = [];
for (let elem in catchData) {
let x = {
startDate: catchData[elem][0],
finishDate: catchData[elem][1]
};
new_data.push(x);
}
return new_data;
};
console.log(mapDateRange(data));

const data = [
["01-08-2019", "08-08-2019"],
["08-08-2019", "15-08-2019"],
["15-08-2019", "22-08-2019"],
["22-08-2019", "29-08-2019"]
];
const mapDataRange = (data) => {
const result = [];
data.forEach((item) => {
const x = { 'startDate': item[0], 'finishDate': item[1] };
result.push(x);
});
return result;
}
console.log(mapDatatRange(data));

In this way you will get your desire result by using map function
data = data.map((obj) => {
return {
startDate: obj[0],
finishDate: obj[1]
}
});
console.log(data)

try to do with .map and array destructuring with ES6 syntax
data.map(([ startDate, finishDate ]) => { startDate, finisDate })

Related

How to update an object value in array of objects when the keys are same

I have an Array of objects and one object
const filterArray = [{bestTimeToVisit: 'Before 10am'}, {bestDayToVisit: Monday}]
This values are setting in a reducer and the payload will be like
{bestTimeToVisit: 'After 10am'}
or
{bestDayToVisit: Tuesday}.
So what I need is when I get a payload {bestTimeToVisit: 'After 10am'} and if bestTimeToVisit not in filterList array, then add this value to the filterList array.
And if bestTimeToVisit already in the array with different value, then replace the value of that object with same key
if(filterArray.hasOwnProperty("bestTimeToVisit")) {
filterArray["bestTimeToVisit"] = payload["bestTimeToVisit"];
} else {
filterArray.push({"bestTimeToVisit": payload["bestTimeToVisit"]});
}
I convert the object array into a regular object and then back into an object array. makes things less complicated. I'm making the assumption each object coming back only has one key/value and that order doesnt matter.
const objectArraytoObject = (arr) =>
arr.reduce((acc, item) => {
const key = [Object.keys(item)[0]];
return { ...acc, [key]: item[key] };
}, {});
const newValues = [{ someKey: 'something' }, { bestDayToVisit: 'Tuesday' }];
const filterArray = [
{ bestTimeToVisit: 'Before 10am' },
{ bestDayToVisit: 'Monday' },
];
const newValuesObj = objectArraytoObject(newValues);
const filterObj = objectArraytoObject(filterArray);
const combined = { ...filterObj, ...newValuesObj };
const combinedToArray = Object.keys(combined).map((key) => ({
[key]: combined[key],
}));
console.log(combinedToArray);
Need to iterate over the array and find objects that satisfy for modification or addition if none are found.
function checkReduced(filterrray,valueToCheck="After 10am"){
let isNotFound =true;
for(let timeItem of filterrray) {
if(timeItem.bestTimeToVisit && timeItem.bestTimeToVisit !== valueToCheck) {
timeItem.bestTimeToVisit=valueToCheck;
isNotFound=false;
break;
}
}
if(isNotFound){filterrray.push({bestTimeToVisit:valueToCheck})}
}
const filterArray = [{bestDayToVisit: "Monday"}];
checkReduced(filterArray,"After 9am");//calling the function
const updateOrAdd = (arr, newItem) => {
// get the new item key
const newItemKey = Object.keys(newItem)[0];
// get the object have the same key
const find = arr.find(item => Object.keys(item).includes(newItemKey));
if(find) { // the find object is a reference type
find[newItemKey] = newItem[newItemKey]; // update the value
} else {
arr.push(newItem); // push new item if there is no object have the same key
}
return arr;
}
// tests
updateOrAdd([{ a: 1 }], { b: 2 }) // => [{ a: 1 }, { b: 2 }]
updateOrAdd([{ a: 1 }], { a: 2 }) // => [{ a: 2 }]

Loop through array for each value from another array

How can I loop through this array:
const counts = [
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk",
];
taking each value from this array?
const uniqueDomains = [
'google.com',
'com',
'mail.yahoo.com',
'yahoo.com',
'mobile.sports.yahoo.com',
'sports.yahoo.com',
'stackoverflow.com',
'overflow.com',
'com.com',
'en.wikipedia.org',
'wikipedia.org',
'org',
'm.wikipedia.org',
'mobile.sports',
'sports',
'google.co.uk',
'co.uk',
'uk'
]
I need to find out if string from counts array includes string from uniqueDomains array.
Then push it to the empty object as a key value pairs, where value
is going to be the number in the beginning of the each string from counts array.
I tried this code but it give me wrong result in my object's values(since I am looping twice)
I need kind of avoid looping twice, but I am not sure how.
Example com is mentioned 8 time in counts array, which means result should be this {com: 1345}
Here is my code:
const finalObject = {}
uniqueDomains.forEach((dom) => {
counts.forEach((cnt) => {
if (cnt.includes(dom)) {
const num = parseInt(cnt);
sumArr.push(num);
const res = sumArr.reduce((acc, cur) => {
return acc + cur;
});
finalObject[dom] = res;
}
});
});
Theres not really any avoiding looping twice (at least), but you can certainly make your code a bit easieer by first turning the count array into an array of val & domain separately.
const countIdx = counts.map(x => {
const [val,domain] = x.split(",");
return {val:parseInt(val,10), domain}
});
Then its just a case of looping the uniqueDomain array and finding all the domaion which match and summing up the val
const result = uniqueDomains.reduce( (res, d) => {
const count = countIdx.filter(x => x.domain.includes(d)).reduce( (acc,x) => acc + x.val,0);
return {...res, [d]:count}
},{});
Live example follows:
const counts = [
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk",
];
const uniqueDomains = [
'google.com',
'com',
'mail.yahoo.com',
'yahoo.com',
'mobile.sports.yahoo.com',
'sports.yahoo.com',
'stackoverflow.com',
'overflow.com',
'com.com',
'en.wikipedia.org',
'wikipedia.org',
'org',
'm.wikipedia.org',
'mobile.sports',
'sports',
'google.co.uk',
'co.uk',
'uk'
]
const countIdx = counts.map(x => {
const [val,domain] = x.split(",");
return {val:parseInt(val,10), domain}
});
const result = uniqueDomains.reduce( (res, d) => {
const count = countIdx.filter(x => x.domain.includes(d)).reduce( (acc,x) => acc + x.val,0);
return {...res, [d]:count}
},{});
console.log(result);
Maybe try something like:
let finalObject = {}
uniqueDomains.forEach((dom) => {
finalObject[dom] = 0;
counts.forEach((cnt) => {
if (cnt.includes(dom)) {
finalObject[dom] += parseInt(cnt);
}
});
});

Array Split Inside Objects

I have an object Regions{} which stores multiple objects, following code block showing countryName : [regions,..,..]
Regions = { Afghanistan:["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"]
Albania:["Berat~01", "Dibër~09", "Durrës~02",]
}
Which giving me result like this:
Afghanistan: Array(n)
0: "Badakhshan~BDS"
1: "Badghis~BDG"
what I am trying to achive is :
Afghanistan: Array(n)
0:{value: "Badakhshan", lable: "BDS"}
1:{value: "Badghis", lable: "BDG"}
thanks in advance
PS: for the sake of some ruthless fellows following is the code what I have tried yet
let countries = CountryRegionData
let regions = {}
countries = countries.map(country => {
regions = {
...regions,
[country[0]]: country[2].split('|')
}
return {
value: country[1],
label: country[0]
}
})
console.log("countries",countries)
console.log("regions",regions)
let values = regions["Afghanistan"];
values = values.map(value =>{
return {
value: value,
lable: value
}
})
You can use split and map, this code is changing values in original object, if you want to build a new object you can use reduce instead of forEach
let Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
}
Object.entries(Regions).forEach(([key,value])=>{
Regions[key] = value.map(data=>{
let [value,label] = data.split('~')
return {value,label}
})
})
console.log(Regions)
Do something like:
Regions.map(region => region.map(txt => {
const [val, lbl] = txt.split("~");
return { value: val, lable: lbl};
}));
Messy but gets the work done. Using nested forEach loops
var Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
}
var ar = [];
Object.keys(Regions).forEach(function(e) {
Regions[e].forEach(function(k) {
var arr = k.split('~');
ar.push({
value: arr[0],
label: arr[1]
})
})
Regions[e] = ar;
ar = [];
})
console.log(Regions)
Use the map function to iterate the object.
Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
};
const finalObject = Object.keys(Regions).map(region => {
return {
[region]: Regions[region].map(country => {
const [value, lable] = country.split("~");
return {
value,
lable
};
})
};
});
console.log(finalObject);

Filter data inside array object of array object using javascript

I am trying to filter data inside array object of array object, Please find below code for more information.
var data = [
{
name:'testdata1',
subdata:[{status:'fail'},{status:'success'}]
},
{
name:'testdata2',
subdata:[{status:'fail'},{status:'success'}]
}
]
Expected Data:
var successdata = [
{
name:'testdata1',
subdata:[status:'success'}]
},
{
name:'testdata2',
subdata:[status:'success'}]
}
];
var FailureData =[
{
name:'testdata1',
subdata:[{status:'fail'}]
},
{
name:'testdata2',
subdata:[{status:'fail'}]
}
];
I missed curly braces,So i am updating
Hope this helps.
const data = [{
name: 'testdata1', subdata: [{status: 'fail'}, {
status:
'success'
}]
},
{
name: 'testdata2', subdata:
[{status: 'success'}, {status: 'fail'}]
}
];
const filterData = (data, status) => data.reduce((acc, val) => {
const sub = val.subdata.map((v) => v.status === status ? ({ name: val.name, subdata: [v] }) : null).filter(f => f !== null);
return acc.concat(sub);
}, []);
const successData = filterData(data, 'success');
const failureData = filterData(data, 'fail');
console.log('successData', successData);
console.log('failureData', failureData);
You could map your arrays using Array.map():
var successData = data.map(item => ({name: item.name, subdata:[{status:'success'}]})
What I guess you want to do is filter the array based on subdata status.
I also guess that what subdata should have is just the status property and your code would be: var data = [{name:'testdata1',subdata:[{status:'fail'},{status:'success'}] }.
Then you want to look in the subdata array and find which data have success and failure in them.
So what you could be looking for is this:
var successData = data.filter(sdata => {
var successFlag=false;
sdata.subdata.forEach(subdata=>{
if (subdata.status==='success'){
successFlag = true;
}
}
return successFlag;
}
The same with the failureData.
For more information you could check the Array.prototype.filter function:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
P.S. As mentioned in a comment to your question as well, your subdata array cannot be an object with two of the same property
var data = [{name:'testdata1',subdata:[{status:'fail'}, {status:'success'}] },{name:'testdata2',subdata:[{status:'success'}, {status:'fail'}] }]
var successData = filterByStatus('success', data);
var failureData = filterByStatus('fail', data);
function filterByStatus(status, data) {
return data.map(d => {
var newObj = Object.assign({}, d);
newObj.subdata = newObj.subdata.filter(s => s.status === status);
return newObj;
});
}
console.log('successData', successData);
console.log('failureData', failureData);
one of possible ways to do what you want if you have one success property in your object

Javascript Loops: for-loop works but not map?

I'm working with mockData for a web app and I'm trying to loop over nested objects. My problem is that a for loop works but not array.map and don't know why.
Here is the for loop:
for (let i = 0; i < fakeChartData.length; i++) {
for (let j = 0; j < fakeChartData[i].poll.length; j++) {
if (fakeChartData[i].poll[j].id === id) {
return fakeChartData[i].poll[j]
}
}
}
And here is the map loop:
fakeChartData.map(data => {
data.poll.map(data => {
if (data.id === id) {
return data;
}
});
});
My Data structure:
fakeChartData = [
{
id: '232fsd23rw3sdf23r',
title: 'blabla',
poll: [{}, {}]
},
{
id: '23dgsdfg3433sdf23r',
title: 'againBla',
poll: [{}, {}]
}
];
I'm trying to load the specific object with the id passed to it on onClick method.
Here is the full function:
export const fetchPollOptById = (id) =>
delay(500).then(() => {
for (let i = 0; i < fakeChartData.length; i++) {
for (let j = 0; j < fakeChartData[i].poll.length; j++) {
if (fakeChartData[i].poll[j].id === id) {
return fakeChartData[i].poll[j]
}
}
}
});
A return statement inside a for loop causes your function to return. However, a return statement inside a .map() function's callback only returns the callback and this returned value is then placed in the new array. Please see the documentation.If you really want to be using .map(), you could do it like this:
export const fetchPollOptById = (id) => {
var result;
fakeChartData.map(data => {
data.poll.map(data => {
if (data.id === id) {
result = data;
return data;
}
});
});
return result;
}
note: I also assume that your poll objects have an id field like this:
fakeChartData = [
{
id: '232fsd23rw3sdf23r',
title: 'blabla',
poll: [
{id: 'pollId1', otherField: 'blah'},
{id: 'pollId2', otherField: 'blah'}
]
},
{
id: '23dgsdfg3433sdf23r',
title: 'againBla',
poll: [
{id: 'pollId3', otherField: 'blah'},
{id: 'pollId4', otherField: 'blah'}
]
}
];
You can then get the poll data like this:
fetchPollOptById("pollId3"); //returns {id: "pollId3", otherField: "blah"}
If I'm right about what you're trying to do, this should work:
return fakeChartData.reduce((acc, data) => acc.concat(data.poll), [])
.filter(pollObj => pollObj.id === id)[0]
First it makes an array containing all the poll objects from different data objects, then it filters them to find the one with the correct id and returns that object.
As to why your approach using map does not work: you are using it in the wrong way. What map does it to take a function and apply it to every member of an array.
Here's an array and function kind of like yours:
const arr = [1,2,3]
const getThingById(id) => {
var mappedArray = arr.map(x => {
if(x === id) return x
})
console.log(mappedArray) // [3]
}
getThingById(3) // undefined
This won't work. getThingById has no return statement. The return statement return x is returning something from the function that is passed into map. Basically, you shouldn't be using map to do what you're trying to do. map is for when you want to return an array.
Try this
fakeChartData.map(data => {
var result = data.poll.map(data => {
if (data.id === id) {
return data;
}
});
return result;
});
It should work. And yeah you should use find() instead of map() I think.
A bit long implementation:
let results = fakeChartData.map(data => {
let innerResult = data.poll.filter(data => {
if (data.id === id) {
return data;
}
return innerResult.length ? innerResult[0] : null;
});
})
.filter(x => (x !== null));
let whatYouwant = results.lenght ? results[0] : null;
If you can use find() it would look nicer, but that depends on what browsers you need to support

Categories