How to use lodash to map an element of a collection and find first that matches criteria? - lodash

I frequently find myself writing code like this:
_.chain([1,2,3]).map(i=>"*"+i+"*").find(i=>i === "*2*").value()
or
_.chain([1,2,3]).map(i=> i === 2 ? "*"+i+"*" : undefined).find(i=>i !== undefined).value()
to transform each element of the collection and get the first element that matches given criteria.
Is there a shorter way to write this in lodash?

Use _.transform. The code below will get the first element you want, transform the data for you and stop the loop at first match.
_.chain(_.range(1,4))
.transform( (r,v) => !(v === 2 && r.push( `*${v}*`)))
.head().value()

Related

How to implement Linked List Recursion in KOtlin

I am learning linked list and came across a problem where you are required to reverse a linked list using recursion. Here is the code I wrote:
fun reverseRecurseTraverse1(firstNode: Node<Int>?): Node<Int>? {
if (firstNode?.next == null) {
return firstNode
} else {
val finalNode = reverseRecurseTraverse1(firstNode.next)
finalNode?.next = firstNode
firstNode.next = null
return finalNode
}
}
Input:
01234
Output:
40
I get the desired output If I change the line from
finalNode?.next = firstNode
to
firstNode.next!!.next = firstNode
What am I doing wrong here?
When I try to whiteboard finalNode?.next = firstNode makes perfect sense to me and based on my understanding those two lines are essentially doing the same thing.
Kindly help me understand this.
It would be useful if you share your "whiteboard logic" and why do you assume finalNode?.next = firstNode is correct and functionally the same as firstNode.next!!.next = firstNode.
Let's get your example: 01234. In the first step firstNode is 0 and after reversing of the remaining sublist, we get 4321. finalNode points at the first element of this reversed sublist, so at 4. Then you add 0 after 4 which is wrong. You should add 0 after 1.
On the other hand, firstNode.next is still pointing at the item that was next to 0 in the original list. It points at 1. By assigning to its next we add 0 where it should be - after 1.
You are almost there, but one line is wrong.
What you are doing is:
If your item is null, return it. That seems okay.
If your item is already the last item, return it as first item. Also looks okay.
If your item is not the last item, reverse the rest of the list. Okay.
Take the old last and now first item, and append your old first now last item to it? That doesn't seem right. Don't you want to append your old first and now last item to the last item of the reversed rest?
It would probably help to write a function
fun Node.last(): Node? = if(next == null) this else next!!.last()
that provides the last item of a linked list.
You could use that to append your previously first item to the last item of the reversed rest.
Considering a call reverseRecurseTraverse1(x), can we maybe always tell what reverseRecurseTraverse1(x).last() is without calculating it?

Vue - How modify this code so not new selects shows up?

This fiddle has almost all I want:
http://jsfiddle.net/jjpfvx5q/1/
However I want just the first sub select to appear.
As for now, if you first select first item in main select and something from the sub select that appaears, and go back to main and select second option, then a new third selectbox is appearing.
I don't want that to happen. I just want to have one main select and a second that populates depending on choice in the first one. So just these two, no matter of how many times I reselect from the main one.
I am new to Vue and find it hard to see where to make that change.
The problem is, when you select a city, you are pushing same cities into cityPacks array. No matter what, exists or not, performing this action. That populates new selectbox according to new data.
Simply, you can empty your cityPacks array before switch statement.
this.cityPacks = [];
#TugayÄ°lik's answer is correct, but in case you want to retain a 'history' of use selections in cityPacks, you can add a v-if to the second select
v-if="index === coInit.map(co => co.id).indexOf(country)"
There's probably some other optimizations you could make to the data structures, depending on the intention of the app. For instance, it's not clear why you use getCities method and not just nest the cities inside the coInit array (and why you need to use setTimeout).
You could also use a coumputed to get the cities for the second select
computed: {
cities() {
return this.country ?
? this.country === 2 ? this.cFrance
? this.country === 3 ? this.cUSA
: []
}
},

Dgrid selection mix-in issue with order

I've been having issues with the dgrid selection mix-in with multi selects.
Using the selection property (for example)
var selected = Object.keys(datatable.selection)
it returns an array of row ids as expected. However the ORDER of those ids seems to be "arbitrary". It seems perhaps that the order of selecting has an affect.
In any event, in the datatable, I want the selected rows to be returned in order that they display in the list, and they do not.
I can get them in the proper order using dojo.query(".dgrid-selected", datatable.domNode), and use the HTML element to get the row data, but this seems like a hack.
I cannot find a proper method to do this on the SitePen docs. Anyone?
I don't think that there is a direct way to do that. The Object.keys(datatable.selection) returns the array of ids in the order in which the rows are selected. You can use some built-in functions of d-grid and JS to achieve this. Below are the steps:
Get the id by Object.keys.
var selected = Object.keys(datatable.selection)
Create a list of objects comprising of id and rowIndex of element
Code:
var dataList= [];
for(var i=0; i< selected.length; i++){
dataList.push({id: selected[i], index: datatable.row(selected[i]).element.rowIndex});
}
Sort the list using index as the attribute:
dataList.sort(function(a, b){ return a.index- b.index; })
The resulting dataList would have the list of objects in order in which they appear in the grid.

How to clear datatable filters?

Im using custom filtering for my datatable using the method:
$.fn.dataTableExt.afnFiltering.push("custom filter function");
This function adds a filter to my datatable.
The problem is that when I use ajax to create an other datatable object, this filter persists and is applied to this other table that should have nothing to do with this filter. How do I clear the filter or bind it to the first datatable only?
if you make a push on $.fn.dataTableExt.afnFiltering, it means it's an array. So when you receive your data, you can remove the filter reference in this array by using :
delete $.fn.dataTableExt.afnFiltering[index or key];
this method will set the element to undefined
or by using the splice method in javascript.
$.fn.dataTableExt.afnFiltering.splice(index,1);
this method will remove the element from the array.
so
var index = $.fn.dataTableExt.afnFiltering.indexOf("custom filter function");
$.fn.dataTableExt.afnFiltering.splice(index,1);
should resolve your problem
(you can have precision here Javascript - remove an array item by value as indexOf is not supported by IE<9)
If you are going to use the 1.10+ version of the datatable in the future, the use of the search plug-in document is shown below:
Search plug-in development
To reset the filter for version 1.10+, simply add any of the following;
$.fn.dataTable.ext.search = [];
$.fn.dataTable.ext.search.pop();
after this blocks you can add;
table.draw();
$.fn.dataTableExt.afnFiltering.pop();
credit to #DrewT
As mentioned from #kthorngren, there is no build in way of tracking, if or how much custom searches are active.
If you are sure, that there is only one custom search is active a
$.fn.dataTableExt.afnFiltering.pop();
will work - there is big BUT:
$.fn.dataTable.ext.search is an array which contains the search settings for custom search and for searchPanes.
An erasing of this array with $.fn.dataTable.ext.search = []; or two pop()'s, allthough there is only one custom search is active --> will brake searchPanes.
e.g. if you have three panes active, this would mean:
$.fn.dataTable.ext.search[0] -> SearchPane Col1
$.fn.dataTable.ext.search[1] -> SearchPane Col2
$.fn.dataTable.ext.search[2] -> SearchPane Col3
$.fn.dataTable.ext.search[3] -> Custom Search -> safe to delete
$.fn.dataTable.ext.search[4] -> Custom Search -> safe to delete
Following code does the job in my case:
let lenOfSearchPanes = dt.settings()[0]._searchPanes.c.columns.length;
let lenOfSearchArr = $.fn.dataTable.ext.search.length;
let diff = lenOfSearchArr - lenOfSearchPanes
if (diff > 0) {
$.fn.dataTable.ext.search = $.fn.dataTable.ext.search.slice(0, -diff);
}

grid filter in dojo

can any one help with filtering multiple condition in dojo grid.
im using grid.DataGrid and json data.
data1 = {items: [ {"id":1,"media":"PRINT",pt:"Yellow Directory"},
{"id":2,"media":"DIGITAL",pt:"Social Media"},{id":3,"media":"DIGITAL",pt:"Yellow Online"}
],identifier: "id"};
a=1,b=2;
grid.filter({id:a,id:b})
the above line is just displaying the record with b value.
i need the record with both the values.
can any one help me with this.???
So you want the records that have any of the specified ids?
It comes down to the capabilities of the store you're using. If you're using a Memory store with SimpleQueryEngine, then you can specify a regex or an object with a test function instead:
grid.filter({id: {
test: function(x) {
return x === 'a' || x === 'b';
}
}});
If you're using JsonRest store, then you get to choose how your queries are processed server-side so you could potentially pass in an array of interesting values and handle that in your own way on the server. (i.e. filter({id:[a,b]}))