Map through an inner array of an Object - javascript

I have this object:
let arr = [{
id : 1,
usr : 'pimba',
xyz: null
},
{
id : 2,
usr : 'aloha',
xyz: {
xyz_id: 2
}
},
{
id : 3,
age : 'pruu',
xyz: null
}];
As you can notice, sometimes xyz is null and sometimes it's not.
I need to recognize whether it is null or not, so I can read it.
I was trying to use map() function but I can't set some sort of filter to only execute the annonymous function when it is NOT null.
I managed to do something like this:
let result = Object.values(arr).map(function(row){
if(row['xyz'] != null) {
console.log(row['xyz_id']);
}
});
what If I want a new array containing ONLY xyz_id ? Is there a shorter version ?
Second case:
There are more than 1 value inside xyz and it's NOT "named".
let arr = [{
id : 1,
usr : 'pimba',
xyz: null
},
{
id : 2,
usr : 'aloha',
xyz: {
xyz_id: {"value1Here", "Value2Here"}
}
},
{
id : 3,
age : 'pruu',
xyz: null
}];

It seems you want to map the array only for the elements that have not-null xyz property. One option is using both .filter and .map methods. Another option is using the .reduce method:
let result = arr.reduce(function(ret, row) {
// assuming `xyz` can be only `null` or an object
if ( row.xyz !== null ) {
ret.push(row.xyz.xyz_id);
}
return ret;
}, []);

You might want to look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const notNull = arr.filter(elm => elm.xyz !== null);

var a = {one: 1, two: null, three: 3, four: true}
var y = []
let scan = (obj) => {
Object.keys(obj).forEach(x => {
if (obj[x] === null) {
console.log('Its null')
} else {
// Extend here to datatypes
y.push(obj[x])
}
});
}
scan(a)
console.log(y)

Related

Remove empty elements from an array in JavaScript Reactjs

[
{
"stockId":2,"vendorId":1,"vendorCode":"Aya - 01","price":2100
},
null,
null
]
remove the null array from arraylist
arr = [ { "stockId":2,"vendorId":1,"vendorCode":"Aya - 01","price":2100 }, null, null ]
arr = arr.filter(elem => elem != null)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
For example, if you want to remove null or undefined values:
var array = [ { "stockId":2,"vendorId":1,"vendorCode":"Aya - 01","price":2100 }, null, null ];
var filtered = array.filter(function (el) {
return el != null;
});
console.log(filtered);
If you want to remove false values, do something like this
var array = [
{ stockId: 2, vendo`enter code here`rId: 1, vendorCode: 'Aya - 01', price: 2100 },
null,
null,
];
newArray = array.filter(item => !!item);
More simple and concise solution:
let newArray = array.filter(Boolean);
just pass javascript Boolean (builtin) function inside filter as callback function.

TypeScript - Take object out of array based on attribute value

My array looks like this:
array = [object {id: 1, value: "itemname"}, object {id: 2, value: "itemname"}, ...]
all my objects have the same attibutes, but with different values.
Is there an easy way I can use a WHERE statement for that array?
Take the object where object.id = var
or do I just need to loop over the entire array and check every item? My array has over a 100 entries, so I wanted to know if there was a more efficient way
Use Array.find:
let array = [
{ id: 1, value: "itemname" },
{ id: 2, value: "itemname" }
];
let item1 = array.find(i => i.id === 1);
Array.find at MDN: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find
I'd use filter or reduce:
let array = [
{ id: 1, value: "itemname" },
{ id: 2, value: "itemname" }
];
let item1 = array.filter(item => item.id === 1)[0];
let item2 = array.reduce((prev, current) => prev || current.id === 1 ? current : null);
console.log(item1); // Object {id: 1, value: "itemname"}
console.log(item2); // Object {id: 1, value: "itemname"}
(code in playground)
If you care about iterating over the entire array then use some:
let item;
array.some(i => {
if (i.id === 1) {
item = i;
return true;
}
return false;
});
(code in playground)
You can search a certain value in array of objects using TypeScript dynamically if you need to search the value from all fields of the object without specifying column
var searchText = 'first';
let items = [
{ id: 1, name: "first", grade: "A" },
{ id: 2, name: "second", grade: "B" }
];
This below code will search for the value
var result = items.filter(item =>
Object.keys(item).some(k => item[k] != null &&
item[k].toString().toLowerCase()
.includes(searchText.toLowerCase()))
);
Same approach can be used to make a Search Filter Pipe in angularjs 4 using TypeScript
I had to declare the type to get it to work in typescript:
let someId = 1
array.find((i: { id: string; }) => i.id === someId)
You'll have to loop over the array, but if you make a hashmap to link each id to an index and save that, you only have to do it once, so you can reference any objeft after that directly:
var idReference = myArray.reduce(function( map, record, index ) {
map[ record.id ] = index;
return map;
}, {});
var objectWithId5 = myArray[ idReference["5"] ];
This does assume all ids are unique though.

How to change nested object into array

I have a object like this.
var Obj = {
obj1 : {
val : 1,
id : 1
}
obj2 : {
val : 2,
id :2
}
obj3 : {
val : 3,
id :3
}
}
I want my obj1and all sub object into one array so I can retrieve the value. I want array in array because I want to retrieve them, Since it is dynamic I can not use Obj.obj1 therefore I want to push into array.
Can Anybody tell How Can I get that. Thanks for help
Use Object.keys and Array#map methods to convert it to an array but the order is not guaranteed since object properties don't have any order.
var Obj = {
obj1: {
val: 1,
id: 1
},
obj2: {
val: 2,
id: 2
},
obj3: {
val: 3,
id: 3
}
};
var res = Object.keys(Obj).map(function(k) {
return Obj[k];
})
console.log(res);

Remove duplicate object from array javascript [duplicate]

I have this kind of array:
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
I'd like to filter it to have:
var bar = [ { "a" : "1" }, { "b" : "2" }];
I tried using _.uniq, but I guess because { "a" : "1" } is not equal to itself, it doesn't work. Is there any way to provide underscore uniq with an overriden equals function?
.uniq/.unique accepts a callback
var list = [{a:1,b:5},{a:1,c:5},{a:2},{a:3},{a:4},{a:3},{a:2}];
var uniqueList = _.uniq(list, function(item, key, a) {
return item.a;
});
// uniqueList = [Object {a=1, b=5}, Object {a=2}, Object {a=3}, Object {a=4}]
Notes:
Callback return value used for comparison
First comparison object with unique return value used as unique
underscorejs.org demonstrates no callback usage
lodash.com shows usage
Another example :
using the callback to extract car makes, colors from a list
If you're looking to remove duplicates based on an id you could do something like this:
var res = [
{id: 1, content: 'heeey'},
{id: 2, content: 'woah'},
{id: 1, content:'foo'},
{id: 1, content: 'heeey'},
];
var uniques = _.map(_.groupBy(res,function(doc){
return doc.id;
}),function(grouped){
return grouped[0];
});
//uniques
//[{id: 1, content: 'heeey'},{id: 2, content: 'woah'}]
Implementation of Shiplu's answer.
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var x = _.uniq( _.collect( foo, function( x ){
return JSON.stringify( x );
}));
console.log( x ); // returns [ { "a" : "1" }, { "b" : "2" } ]
When I have an attribute id, this is my preffered way in underscore:
var x = [{i:2}, {i:2, x:42}, {i:4}, {i:3}];
_.chain(x).indexBy("i").values().value();
// > [{i:2, x:42}, {i:4}, {i:3}]
Using underscore unique lib following is working for me, I m making list unique on the based of _id then returning String value of _id:
var uniqueEntities = _.uniq(entities, function (item, key, a) {
return item._id.toString();
});
Here is a simple solution, which uses a deep object comparison to check for duplicates (without resorting to converting to JSON, which is inefficient and hacky)
var newArr = _.filter(oldArr, function (element, index) {
// tests if the element has a duplicate in the rest of the array
for(index += 1; index < oldArr.length; index += 1) {
if (_.isEqual(element, oldArr[index])) {
return false;
}
}
return true;
});
It filters out all elements if they have a duplicate later in the array - such that the last duplicate element is kept.
The testing for a duplicate uses _.isEqual which performs an optimised deep comparison between the two objects see the underscore isEqual documentation for more info.
edit: updated to use _.filter which is a cleaner approach
The lodash 4.6.1 docs have this as an example for object key equality:
_.uniqWith(objects, _.isEqual);
https://lodash.com/docs#uniqWith
Try iterator function
For example you can return first element
x = [['a',1],['b',2],['a',1]]
_.uniq(x,false,function(i){
return i[0] //'a','b'
})
=> [['a',1],['b',2]]
here's my solution (coffeescript) :
_.mixin
deepUniq: (coll) ->
result = []
remove_first_el_duplicates = (coll2) ->
rest = _.rest(coll2)
first = _.first(coll2)
result.push first
equalsFirst = (el) -> _.isEqual(el,first)
newColl = _.reject rest, equalsFirst
unless _.isEmpty newColl
remove_first_el_duplicates newColl
remove_first_el_duplicates(coll)
result
example:
_.deepUniq([ {a:1,b:12}, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ],[ 2, 1, 2, 1 ], {a:1,b:12} ])
//=> [ { a: 1, b: 12 }, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ] ]
with underscore i had to use String() in the iteratee function
function isUniq(item) {
return String(item.user);
}
var myUniqArray = _.uniq(myArray, isUniq);
I wanted to solve this simple solution in a straightforward way of writing, with a little bit of a pain of computational expenses... but isn't it a trivial solution with a minimum variable definition, is it?
function uniq(ArrayObjects){
var out = []
ArrayObjects.map(obj => {
if(_.every(out, outobj => !_.isEqual(obj, outobj))) out.push(obj)
})
return out
}
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) {
return JSON.stringify(f);
}), function (gr) {
return gr[0];
}
);
Lets break this down. First lets group the array items by their stringified value
var grouped = _.groupBy(foo, function (f) {
return JSON.stringify(f);
});
grouped looks like:
{
'{ "a" : "1" }' = [ { "a" : "1" } { "a" : "1" } ],
'{ "b" : "2" }' = [ { "b" : "2" } ]
}
Then lets grab the first element from each group
var bar = _.map(grouped, function(gr)
return gr[0];
});
bar looks like:
[ { "a" : "1" }, { "b" : "2" } ]
Put it all together:
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) {
return JSON.stringify(f);
}), function (gr) {
return gr[0];
}
);
You can do it in a shorthand as:
_.uniq(foo, 'a')

How to rewrite an Array.every() in a custom Array.reduce() in javascript?

This question is for purely for learning purposes. funfunfunction on youtube says that
Any list higher order list transformation can be written in Array.reduce()
Audio/video Reference: https://youtu.be/Wl98eZpkp-c?t=138.
Question:
Purely for learning how would one rewrite Array.every() with Array.reduce()
This question stems from my previous question here
Javascript Example:
var approved1 = [
{
dateApproved: new Date(),
id: 1,
},
{
dateApproved: new Date(),
id: 2,
}
];
var approved2 = [
{
dateApproved: null,
id: 1,
},
{
dateApproved: new Date(),
id: 2,
}
];
approved1.every(a => a.dateApproved != null) ? 'APPROVED' : 'PENDING'
// 'APPROVED'
approved2.reduce(every) ? 'APPROVED' : 'PENDING'
// 'PENDING'
I struggle with where I store the currently passed values. Where do I store the "passed" values like Array.every() does?
function every(previousValue, currentValue, currentIdx, arr) {
if(previousValue.dateApproved !== null && currentValue.dateApproved !== null) {
return currentValue;
}
}
You can use reduce instead of every and make it work, but I'd suggest you to use them in there apt places. Both have distinctive requirement.
array.reduce
array.reduce(callback(curentElement, nextElement, index, array),[initialCurrentElement])
Array.reduce has 4 args.
currentElement: By default, this will be 1st element in array for 1st iteration and then, this variable will hold value that you return. If an initial value is passed, then it will hold that and start from there.
nextElement: By default it holds second or next element. If initial value is passed, this will hold first value.
index: this holds the index of current element.
array: This is the parent array on which we are looping.
initialCurrentElement: This is an optional argument. If this is passed, looping starts with this.
Following is a sample showing an illustration:
Note:
Array.every will break on first falsey condition. Array.reduce will not.
Array.reduce is meant to compare 2 values of same array where as Array.every is meant to compare each values to an expression. Using .reduce instead of .every is just an overkill.
var approved2 = [{
dateApproved: null,
id: 1,
}, {
dateApproved: new Date(),
id: 2,
}];
var everyResult = approved2.every(x => {
console.log(x.dateApproved)
x.dateApproved !== null
})
console.log(everyResult)
var reduceResult = approved2.reduce((p, c) => {
console.log(c.dateApproved)
return !p ? p : c.dateApproved !== null
}, true)
console.log(reduceResult? 'Approved': 'Rejected')
This should do the trick:
function every(pre, curr) {
return pre.dateApproved != null && curr.dateApproved != null
}
approved1.reduce(every) ? 'APPROVED' : 'PENDING' // APPROVED
approved2.reduce(every) ? 'APPROVED' : 'PENDING' // PENDING
And I'm pretty sure you can do it without curr, just pre.
var status = approved1.reduce( val => (val.dateApproved) ? 'APPROVED': 'REJECTED')
var approved1 = [
{
dateApproved: new Date(),
id: 1,
},
{
dateApproved: new Date(),
id: 2,
}
];
var approved2 = [
{
dateApproved: new Date(),
id: 1,
},
{
dateApproved: null,
id: 2,
},
{
dateApproved: new Date(),
id: 2,
}
];
console.log(approved2.reduce( (prev, curr) => (prev.dateApproved && curr.dateApproved) ? true : false) ? 'APPROVED':'REJECTED')
console.log(approved1.reduce( (prev, curr) => (prev.dateApproved && curr.dateApproved) ? true : false) ? 'APPROVED':'REJECTED')
You might roughly implement it as folows
Array.prototype.every = function(cb){
return this.reduce((p,c,i,a) => i === 1 ? cb(p,i-1,a) && cb(c,i,a)
: p && cb(c,i,a));
};
var arr = [9,2,3,9,12,5],
brr = [1,2,3,4,5,6,9];
console.log(arr.every(e => e < 10));
console.log(brr.every(e => e < 10));

Categories

Resources