Push object into an array in javascript [duplicate] - javascript

This question already has answers here:
How can I group an array of objects by key?
(32 answers)
Closed 4 years ago.
object is not pushing into array.
groupEventsArray=[]
groupEvents=(eventOnDate)=>{
for(i=0;i<eventOnDate.events.length;i++){
for(j=0;j<eventOnDate.events.length;j++){
if(eventOnDate.events[i].start==eventOnDate.events[j].start)
this.groupEventsArray.push(eventsOnDate.events[i])
}
}
console.log(JSON.stringify(this.groupEventsArray))
}
No error is coming but I think it is stucked in infinite loop.
Any help will be appreciated

Consider using forEach() method. The forEach() method calls a provided function once for each element in an array, in order.
Note: forEach() does not execute the function for array elements without values.
Syntax
array.forEach(function(currentValue, index, arr), thisValue)
Example
var numbers = [4, 9, 16, 25];
function myFunction(item, index) {
console.log(item, index);
}
numbers.forEach(myFunction)
Looping over an array like this help avoid infinte loop.

Sounds like a basic group array by key question. You could do it in the following way:
const data = {
fullDate: '2018-10-26T09:30:00.000Z',
events: [
{
eventId: '43460',
start: '1540525500',
},
{
eventId: '43461',
start: '1540525500',
},
{
eventId: '43462',
start: '1540525500',
},
{
eventId: '43463',
start: '1540525510',
},
],
};
const createKey = (t) => t.start;
console.log(
Object.values(
data.events
.map((o) => [o, createKey(o)])
.reduce((result, [item, key]) => {
result[key] = result[key] || [];
result[key].push(item);
return result;
}, {}),
),
);
But the question is probably a duplicate of this one (look for answers not using lodash)

Related

Convert Json Array to single Object in Node JS [duplicate]

This question already has answers here:
Merge multiple objects inside the same array into one object [duplicate]
(2 answers)
How to concatenate properties from multiple JavaScript objects
(14 answers)
Closed 1 year ago.
I want to convert JSON array to a single object. PFB the details
Array:
[{ "item-A": "value-1" }, { "item-B": "value-2" }]
Expected Result:
{ "item-A": "value-1", "item-B": "value-2" }
I have tried following options but result is not what I was expecting
let json = { ...array };
json = Object.assign({}, array);
json = array.reduce((json, value, key) => { json[key] = value; return json; }, {});
Result:
{"0":{"item-A":"value-1"},"1":{"item-B":"value-2"}}
You can use Object.assign and spread the array
const arr=[{ "item-A": "value-1" }, { "item-B": "value-2" }];
console.log(Object.assign({},...arr));
You can use reduce like how you did it with more attention like this:
let array = [{ "item-A": "value-1" }, { "item-B": "value-2" }];
let object = array.reduce((prev, curr) => ({ ...prev, ...curr }), {});
console.log(object);

JavaScript map returning array of objects instead of ojbect [duplicate]

This question already has answers here:
Why does JavaScript map function return undefined?
(13 answers)
Find object by id in an array of JavaScript objects
(36 answers)
Closed 4 months ago.
Javascript method returns array of object instead of object.
Helper method:
export const getDefaultValue = (valueList) => {
return defaultValue = valueList.map((item, index) => {
if (item.isDefault) {
return item;
}
});
}
Input:
let valueList = [{itemId: 1, isDefault: true}, {itemId: 2, isDefault: false}, {itemId: 3, isDefault: false}]
When calling getDefaultValue(valueList), I'm getting below output:
Output:
[{itemId: 1, isDefault: true}, undefined, undefined]
Shouldn't getDefaultValue return only {itemId: 1, isDefault: true}?
Newbie to JavaScript. What am I missing here?
map isn't right for this - use find:
export const getDefaultValue = (valueList) => {
return defaultValue = valueList.find((item, index) => {
if (item.isDefault) {
return true;
}
});
}
You could also simplify it:
export const getDefaultValue = valueList => valueList.find(({ isDefault }) => isDefault);
Since you just want to get the one matching value from the array, you should use .find instead:
export const getDefaultValue = (valueList) => {
return defaultValue = valueList.find((item) => {
if (item.isDefault) {
return true;
}
});
};
.map will always construct a new array, based on all items of the old array, which isn't what you want here.
You need to filter the array with Array#filter and this returns either the element or not, depending on the return value.
return defaultValue = valueList.filter(item => item.isDefault);
Array#map returns a new element for each element.
After a clear problem description, you need to take Array#find for getting a single object.
This method returnd the first found element or undefined if not element fullfills the condition.
return defaultValue = valueList.find(item => item.isDefault);
The Array.Map() method returns array of values. Since you are returning item itself which is an object, the final output becomes array of object.
try this:
export const getDefaultValue = (valueList) => {
return defaultValue = valueList.map((item, index) => {
if (item.isDefault) {
return item.itemId;
}
});
}
which will also capture undefined if nothing gets returned. You can you filter method instead.
const getDefaultValue = valueList.filter(item => item.isDefault);

How to order list item and push something to the beginning of array

I want to order my dynamic data so that if it includes a particular string, push it to the top of the list item. Then push the rest in. I'm confused about how to go about this.
So I have something like
So if it includes overview, push it to the front and rest push after. I'm kind of confused about how to do this.
You can simply use reduce in combination with the unshift and push methods to return a new Array that organizes itself based on whether or not the value of each object includes "overview":
tree.reduce( (acc, cv) => !cv.value.includes( "overview" ) ?
(acc.push(cv), acc) :
(acc.unshift(cv), acc ), []);
//data setup
let tree = ["A","B","overview","C","D","overview","E","overview"].map(_=>Object({value:_}));
//result
let result = tree.reduce((acc, cv) =>
!cv.value.includes( "overview" ) ?
(acc.push(cv), acc) :
(acc.unshift(cv), acc ), []);
console.log( result);
Your code works to push anything with 'overview' to the front with the unshift call. You do not need the last push call as the array is modified in place with unshift.
You can use Array.prototype.sort() method
const values = [
{ value: 'foo' },
{ value: 'bar' },
{ value: 'baz' },
{ value: 'overview' },
]
function toFront(arr, search) {
return arr.sort(a => -a.value.includes(search))
}
console.log(toFront(values, 'overview'))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
You could use reduce to populate two arrays, one for each category, and join them at the end:
// Input
const tree = [{value: "A"},{value:"B"},{value:"overview"},{value:"C"},{value:"D"},{value:"overview"},{value:"E"},{value:"overview"}];
// Transformation
const result = [].concat(...tree.reduce(
(acc, obj) => (acc[1-obj.value.includes("overview")].push(obj), acc),
[[], []]
));
console.log( result);

Is there a nice way in javascript to removing Falsy values from a javascript object (not an array)?

In JavaScript you have the nice .filter method to remove null or falsy values from arrays. So far I haven't been able to find a method to remove the same from JavaScript Objects.
Why would this be?
Currently you can create a function for arrays like :
function stripNulls(arr) {
return arr.filter(Boolean);
}
Is there a similar function that can be created for JS Objects, or is the way filter works not practical on JS Objects.
The answer to "can I do x to an object" (or an array for that matter) is usually "yes" and it frequently involves some form of reduce.
If you want to filter falsy values you could do something like this:
function filterFalsy(obj) {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key]) {
acc[key] = obj[key]
}
return acc
}, {})
}
const testObj = {
a: 'test',
b: 321,
c: false
}
console.log(filterFalsy(testObj))
This returns a new object without falsy values and leaves the existing object alone.
WARNING: There are better answers provided here. Also, thanks to comments made below user's should be warned using delete may provide suboptimal performance.
Filtering invalid values is a little more complex in objects. At face value this will do what you want:
var arr = [ 'apple', 43, false ];
var trueArr = arr.filter(Boolean);
console.log(trueArr);
var obj = { 'title': 'apple', 'id': 43, 'isOrange': false, 'test': 'asd' };
Object.keys(obj)
.filter(key => !obj[key])
.forEach(key => delete obj[key]);
console.log(obj);
However, this will not iterate over child objects / functions. This logic also directly modifies the original object (which may or may not be desired).
That can easily changed by adding this logic to a function like so:
function removeFalseyProperties(obj) {
Object.keys(obj)
.filter(key => !obj[key])
.forEach(key => delete obj[key]);
return obj;
}
var testObj = { 'title': 'apple', 'id': 43, 'isOrange': false, 'test': 'asd' };
var trutheyObj = removeFalseyProperties(testObj);
console.log(trutheyObj);
falsy values are 0, undefined, null, false, etc.
myArray
.map(item => {
// ...
})
// Get rid of bad values
.filter(Boolean);
By passing Boolean we can remove all the falsy values.

How can I filter by all the properties in an array of objects? [duplicate]

This question already has answers here:
Filter array of objects on all properties value
(3 answers)
Closed 5 years ago.
Suppose I have an array like this:
const people = [
{
"name":"pete22",
"age":56
},
{
"name":"sonya56",
"age":22
}
]
I can filter with lodash like this by name:
let result = people.filter(person =>_.includes(person.name,'56')
//{'name':'sonya56'}
What if I want to return all people with '56' in any property? So in the above example it would return both people? I am looking for a compact solution, maybe lodash?
You don't need Lodash to do this as JavaScript natively has support to do these kind of things.
What you need to do is filter the people but also filter each value inside an entry, e.g.:
const people = [{
"name": "pete22",
"age": 56
}, {
"name": "sonya56",
"age": 22
}]
// Filter your 'people' JSON
const filteredPeople = people.filter(person => {
// Filter each 'value' (property) inside each entry in 'people'
return Object.values(person).filter(value => {
// Turn a value into a string and check if it includes the value '56'
return value.toString().includes('56')
})
})
console.log(filteredPeople)
You could just use Array#filter with Object.values, Array#map with strings and check with Array#some and Array#includes.
const
people = [{ name: "pete22", age: 56 }, { name: "sonya56", age: 22 }],
filteredPeople = people.filter(person => Object
.values(person)
.map(String)
.some(v => v.includes('56'))
)
console.log(filteredPeople);
What if I want to return all people with '56' in any property?
You need an array with all such properties with which you want to filter the input array.
var prop = [ "age", "size" ];
Now simply applies the filter in a loop
var valueToMatch = "56";
result = people;
prop.forEach( function( key ){
if ( result.length ) { return true; } //if the result is already empty
result = result.filter( function( peopleObj ){
peopleObj[ key ] == valueToMatch;
});
});
result is the output array filtered with all the properties given in prop array.
Stop using lodash for everything.
JavaScript:
let filtered = people.filter((e) => e.name === ‘foo’ && e.age === 23);
Keep in mind that && forces the two conditions and || says that only one of them must be true.
Extended solution for any number of properties:
var people = [
{ "name":"pete22", "age":56 }, {"name":"sonya56", "age":22 },
{ "name":"john33", "age":33 }, {name: "mike", "login":"56mike", "code": 10 }
],
result = people.filter(function(o){
return Object.keys(o).some(function(k){ return String(o[k]).indexOf("56") !== -1; });
});
console.log(result);
We can filter again with values of Object
people.filter(
hm=>Object.values(hm).filter(
vl=>(vl+'').indexOf(56)>-1).length>0)

Categories

Resources