Underscore.js : findWhere with nested property value - javascript

How do I go about the filtering below:
[{
"id": 100,
"title": "Tlt1",
"tax": [{
"name": "Tax1",
"id": 15
}, {
"name": "Tax1",
"id": 17
}]
}, {
"id": 101,
"title": "Tlt2",
"tax": [{
"name": "Tax2",
"id": 16
}]
}, {
"id": 102,
"title": "Tlt3",
"tax": [{
"name": "Tax3",
"id": 17
}, {
"name": "Tax3",
"id": 18
}]
}]
to get only those where tax.id is 17, as per below:
[
{
"id": 100,
"title": "Tlt1",
"tax": [
{
"name": "Tax1",
"id": 15
},
{
"name": "Tax1",
"id": 17
}
]
},
{
"id": 102,
"title": "Tlt3",
"tax": [
{
"name": "Tax3",
"id": 17
},
{
"name": "Tax3",
"id": 18
}
]
}
]
Currently I use the method below, but maybe there is more clean way of going about this?
var arr = [];
_(data).each(function (v1, k1) {
_(v1.tax).each(function (v2, k2) {
if (v2.id == id) {
arr.push(v1);
}
});
});
Demo here: http://jsfiddle.net/7gcCz/2/
Any suggestion much appreciated.

You may use the combination of _.filter and _.where
_.filter(data, function(obj) {
return _.where(obj.tax, {id: ID_TO_FIND}).length > 0;
})
See demo: http://jsfiddle.net/hCVxp/
Update
Thanks to #GruffBunny. A more efficient way is to use _.some to avoid looping through all tax items:
var arr = _.filter(data, function(obj) {
return _.some(obj.tax, {id: ID_TO_FIND});
});
See demo: http://jsbin.com/putefarade/1/edit?html,js,console

Use _.filter to find candidate items and _.some to check for the existence of an item in a collection:
var filteredList = _.filter(list, function(item){
return _.some(item.tax, { id: 17 });
});

You can do this with _.where alone.
var filteredList = _.where(list, { tax:[{id:17}] });
Edit: This method works in older version of lodash, but wont work in current underscore or lodash.
Working example anyway:
https://jsfiddle.net/rhp4crma/

Related

How can I inner join with two object arrays in JavaScript?

I need inner join with two array in javascript like this:
array1 =
[
{
"id": 1,
"name": "Tufan"
},
{
"id": 2,
"name": "Batuhan"
},
{
"id": 3,
"name": "Hasan"
}
]
array2 =
[
{
"name": "yyy",
"externalid": "1",
"value": "Asd"
},
{
"name": "aaaa"
"externalid": "2",
"value": "ttt"
}
]
expectedArray =
[
{
"id": 1,
"name": "Tufan",
"externalid": "1",
"value": "Asd"
},
{
"id": 2,
"name": "Batuhan",
"externalid": "2",
"value": "ttt"
}
]
rules:
on: array2.externalid = array1.id
select: array1.id, array1.name, array2.externalid, array2.value
My approach:
array1.filter(e => array2.some(f => f.externalid == e.id));
// I need help for continue
How can I make this?
Doesn't matter information: I use ES5 and pure javascript
You can do it like this:
const res = array2.map((item) => {
const related = array1.find((el) => el.id == item.externalid);
return { ...item, ...related };
});
Using a map to loop over the array2 and a find to get the array1 relative.

How to groupBy in multi arrays using lodash

I want to group By sub-work in array
Here is my array I want to group By sub-work
result = [
{
"date": "10-07-2019",
"data": [
{
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [
{
"id": 7,
"title": 'subdata-1',
}
]
}
]
},
{
"date": "12-07-2019",
"data": [
{
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [
{
"id": 7,
"title": 'subdata-1',
}
]
}
]
},
]
Here is what I try
result = _(result)
.map(function(items, data) {
_.groupBy(items.data, function({ sub_work }) {
return sub_work;
});
})
.value();
first I map result into data then I try to groupby but It's return null
Update
I want my output look like this
[
{
"date": "10-07-2019",
sub-work: [{
sub-work : "sub_work1",
sub-data[
{
"id": 7,
"title": 'subdata-1',
}
]
}]
}
]
...........................
It would be better if you could provide your expected result.
Here's what I could infer:
_(result)
.map(function(obj) { // Convert into a 2D array.
return obj.data.map(e => Object.assign(e, {date: obj.date}));
})
.flatten() // We have an array of objects now.
.groupBy('sub-work') // We can call groupBy().
.value();
Here's what you get:
{
"sub_work1": [{
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [{
"id": 7,
"title": "subdata-1"
}],
"date": "10-07-2019"
}, {
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [{
"id": 7,
"title": "subdata-1"
}],
"date": "12-07-2019"
}]
}

Accessing nest elements by their keys with d3.js

So I have the following nest:
var myNest = [
{"key":"1","values":[...]},
{"key":"2","values":[...]},
{"key":"3","values":[...]},
]
How can I access these elements using their keys?
I know I can access them by their index
myNext[0] //return elements with key=="1"
myNest[1] //return elements with key=="2"
But what I would like to do is:
myNest["1"] //return elements with key=="1"
myNest["2"] //return elements with key=="2"
Thanks
Use map() instead of entries() when building your nest. You probably did something similar to this:
var products = [{
"id": 1,
"name": "Cat Hat",
"price": 49
}, {
"id": 2,
"name": "Unicorn Boots",
"price": 139
}, {
"id": 3,
"name": "Pink Woolly Jumper",
"price": 34
}];
var productsById = d3.nest()
.key(function(p) {
return p.id;
})
.entries(products);
console.log(productsById)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
If instead you use map():
var products = [{
"id": 1,
"name": "Cat Hat",
"price": 49
}, {
"id": 2,
"name": "Unicorn Boots",
"price": 139
}, {
"id": 3,
"name": "Pink Woolly Jumper",
"price": 34
}];
var productsById = d3.nest()
.key(function(p) {
return p.id;
})
.map(products);
console.log(productsById)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
You get a map where you can access objects by their key directly, e.g. with productsById["2"] in this example.
You could us a hash table, where the key of your object is the key for the object itselft.
For ES6 I suggest to use a Map:
var myNest = [{ key: "1", values: [1, 4] }, { key: "2", values: [2, 5] }, { key: "3", values: [3, 6] }],
hash = Object.create(null);
myNest.forEach(function (a) {
hash[a.key] = a;
});
console.log(hash['2']);

Underscore filter array of object using like query

I have the below Json.
{
"results": [
{
"id": "123",
"name": "Some Name"
},
{
"id": "124",
"name": "My Name"
},
{
"id": "125",
"name": "Johnson Johnson"
},
{
"id": "126",
"name": "Mike and Mike"
},
{
"id": "201",
"name": "abc xyz"
},
{
"id": "202",
"name": "abc befd"
},
{
"id": "210",
"name": "jki yuiu"
},
{
"id": "203",
"name": "asdfui uiuu"
},
{
"id": "204",
"name": "sfdhu uiu"
},
{
"id": "205",
"name": "asdfui uyu"
}
]
}
Using Underscore i want to filter the above data using sql like query on id.
for example if pass "2" the json should be filtered and return a new json which contain id starting with 2, If i pass 20 it should return new json with id starting with 20
similar to sql like query and then return n results matching,
correction: I want the data starting with id 2 or whatever parameter i pass i need data starting with it
Try this
function getResult(keyToFilter, valueStartsWith){
return _.filter(results, function(d){ return d[keyToFilter].startsWith(valueStartsWith); })
}
getResult("name", "asdfui");
[{
"id": "203",
"name": "asdfui uiuu"
},
{
"id": "205",
"name": "asdfui uyu"
}]
What about Array.prototype.filter and Array.prototype.slice? (underscore has similar functions but why to use them when it can be solved with plain JS)
function sqlLikeFilter(data, id, maxn) {
return data.result.filter(function(x) { return x.id == id; }).slice(0, maxn);
}
console.log(sqlLikeFilter(yourData, 125, 1));
Try this
function(id){
var result = _.filter(results, function(value) {
return value.id === id
})
return result;
}

Lodash filter nested object

I have the following object containing an array posts:
var posts = {
"posts": [{
"id": 83,
"title": "Onfido helps iCracked win customers’ confidence",
"slug": "onfido-helps-icracked-win-customers-confidence",
"tags": [{
"id": 25,
"slug": "case-studies"
}, {
"id": 10,
"slug": "industry-news"
}]
}, {
"id": 82,
"title": "Machine learning makes banking more personal",
"slug": "machine-learning-makes-banking-more-personal",
"tags": [{
"id": 10,
"slug": "industry-news"
}]
}, {
"id": 81,
"title": "11 reasons to join Onfido",
"slug": "ten-reasons-to-join-onfido",
"tags": [{
"id": 100,
"slug": "our-expertise"
}]
}]
}
Using Lodash, I’d like to extract all posts with tags.slug of value "case-studies". Currently I’ve been trying the following with no luck:
_.filter(posts, function(post) {
_.filter(post.tags, function(tag) {
return _.where(tag, {'slug': 'case-studies'})
})
})
How would I do this?
Lodash
var out = _.filter(posts.posts, function (post) {
return _.some(post.tags, { 'slug': 'case-studies' });
});
Vanilla JS
var out = posts.posts.filter(function (el) {
return el.tags.some(function (tag) {
return tag.slug === 'case-studies';
});
});

Categories

Resources