Find texbox value match in an array - javascript

I am trying to look for texbox values matching an array I have provided a code snippet below:
$('#message').on('keyup', function () {
suggest_array_sample = [
{ array_val: "#{person1}" },
{ array_val: "#{person2}" },
{ array_val: "#{person3}" }
];
found_variable_array = [];
$.each(suggest_array_sample, function (key, value) {
console.log(value);
if ($.inArray(value, textbox_value)) {
console.log('found');
found_variable_array.push(value);
} else {
console.log('not found');
}
})
console.log(found_variable_array);
});
<textarea id="message"></textarea>
The problem is it always return the whole array instead of just the matches the ouput should be when I type #{person1} on the textbox the output should be
[{array_val:"#{person1}"}] //expected output
[{array_val:"#{person1}"},{array_val:"#person2"}]// expected output when two or more matches are found on the textbox
instead of
[{array_val:"#{person1}"},]{array_val:"#{person2}",{array_val:"#{person3}"}] //current output
is this possible using the inArray() or do I need to change the code.

use filter method of Array.
yourArray.filter ( yourArrayModel => yourArrayModel.fieldValue === yourSearchValue )
In your case yourSearchValue can be “{#person1}”
For more information, look for filter method documentation, i hope this is what you want.

$.inArray return a position, if not found return -1 else return >= 0
The $.inArray() method is similar to JavaScript's native .indexOf()
method in that it returns -1 when it doesn't find a match. If the
first element within the array matches value, $.inArray() returns 0
Try this code
$('#message').on('keyup', function () {
textbox_value = $(this).val();
suggest_array_sample = ["#{person1}", "#{person2}", "#{person3}"];
console.log($.inArray(textbox_value, suggest_array_sample));
});

It's not entirely clear what you're trying to achieve. I've written something using $.inArray that tells you the array index of the found value. You need to use .map() on the array to extract the val you want.
EDIT:
From what I understood of your comment, I've now had the value be added to found_value_array each time the value is found.
Or is it that you want an array to be returned because the same value might appear multiple times?
let found_variable_array = [];
$('#message').on('keyup',function(){
suggest_array_sample = [
{array_val:"#{person1}"},
{array_val:"#{person2}"},
{array_val:"#{person3}"}
]
let index = $.inArray($(this).val(), suggest_array_sample.map(o => o.array_val));
if (index >= 0) found_variable_array.push(suggest_array_sample[index]);
console.log(found_variable_array);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="message"></textarea>

After combining ideas presented here this method work for me
match_value = suggest_array.filter(function(result){
if(textbox_value){
return textbox_value.search(result)>-1
}
else{
return false
}
})
console.log(match_value);

Related

Loop through 2 Arrays and assign a value from one array into each matching objects of second array

I have 2 Arrays 1.Options and 2.sameAccountArray
options.map((opt, optInd) => {
sameAccountArray.map((acObj, acInd) => {
if (opt.optNumber === acObj.optNumber) {
console.log(opt.optNumber, acObj.optNumber, acObj.exist, acObj.exist, 'WTF', sameAccountArray);
opt.exist = acObj.exist;
} else {
console.log(opt, acObj, opt.optNumber, acObj.optNumber, 'kundi');
// opt.exist = false;
}
// else {
// if (optInd === acInd) {
// opt.exist = acObj.exist;
// } else {
// console.log('elseeee', optInd, acInd,opt.optNumber, acObj.optNumber, opt.exist, acObj.exist);
// }
// }
});
});
Data Structure of sameAccountArray:
{
'key': key,
'shares': this.no_of_shares[key],
'refValue': this.your_reference[key],
'exist': false,
'accountNumber': extractedAccountNumber, 'optNumber': parseInt(extractedOptionNumber)
}
Option have big fields inside, but we don't need to care about it. options and sameAccountArray have common filed named optNumber. I am trying loop through each array and assign a value named exist in each object of the options array if optNumber is same. sameAccountArray already has the correct exist value, I just need to assign that value to match objects of options array. Somehow it's not assigned correctly. Please note that options array and sameAccount Array is not the same length. sameAccountArray has dynamic objects while options have a fixed number of elements. Any idea what is going wrong here guys? Thanks in advance
Try this:
options.forEach(opt=>{
sameAccountArray.forEach(acObj=>{
if (opt.optNumber === acObj.optNumber) opt.exist = acObj.exist;
})
})
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
You cannot modify your arrays with map() function, but only create a new array with the results you want.
let sameAccountObject={};
sameAccountArray.forEach((account)=>{
sameAccountObject[account.optNumber]=account;
});
let result=options.map((option)=>{
let account=sameAccountObject[option.optNumber];
if(account){
option.exist=account.exist;
}
return option;
});
console.log(result);

Filter an array of nested objects

I have an array of nested objects and I have a user, which searches for a room
Here is an array of objects.
I would like to filter an array as soon as user types something
I tried a lot of functions, but nothing worked for me, here is the last example, which failed
search(val: any) {
// if input is clear - show everything, what we have
if (val === '') {
this.roomList = this.roomList;
} else {
//choose the object (objects) where rName = val
this.roomList = this.roomList.staticData.rName.filter(function(o) {
return Object.keys(o).some(function(k) {
return o[k].toString().toLowerCase().indexOf(val) != -1;
})
});
}
}
Could you please help or give me a hint?
You need to apply Array.filter() on roomList instead of staticData propety
this.roomList = this.roomList.filter(function (r) {
return r.staticData.rName.toLowerCase().indexOf(val.toLowerCase()) != -1
});
this.roomList = this.roomList.staticData.rName
This is a wrong starting point, just look at it. Then, rName is not an array, so you can't invoke .filter on it.
Here's how to do it :
this.roomListFiltered = this.roomList.filter(o => new RegExp(val,"i").test(o.staticData.rName) )
new RegExp(val,"i") performs a case-insensitive match.
Also, store the result of the filter in a different variable, otherwise you will lose your original list as it gets filtered out.

Javascript filter and match all elements in array

I have an array that looks like:
var testArr = ["40", "A1", "B9", "58"]
I want to loop over all div elements of a certain class and return only the elements where the data attribute matches ANY of the items in that array.
If I do something like this:
$("div.prodCodes").filter(function(e) {
var x1 = $(this);
var x2 = $(this).data("prodCode");
testArr.forEach(function(e) { if (e == x2) { console.log("MATCH"); } });
});
That console outputs the correct number of matches, but I cannot return those elements from the filter function.
What on earth am I missing here? I've tried creating a new array and pushing each item onto it and returning that, but it's always empty. I'm sure I'm missing something obvious here. I've also tried rewriting this using .grep() and getting nowhere. Help is appreciated.
You need to return a truthy value in filter() to have an item included.
Try :
$("div.prodCodes").filter(function(e) {
return testArr.indexOf($(this).attr('data-prodCode')) >-1;
}).doSomething();
Without a return all items will be excluded
I would use a Set for constant-time lookup.
Be aware that jQuery reads the attribute value "58" as a number when using the data method, so it won't match unless you make sure the data type is the same:
// Use a set
var testSet = new Set(["40", "A1", "B9", "58"]);
var texts = $("div.prodCodes").filter(function() {
var x = $(this).data("prodCode").toString(); // data type must match
// Return a boolean to indicate whether the div element should be kept
return testSet.has(x); // Set#has() is fast
}).map(function(){
// For demo only: get the text content of the matching div elements
return $(this).text();
}).get(); // convert that to a plain array
console.log(texts);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="prodCodes" data-prod-code="A1">Hello</div>
<div class="prodCodes" data-prod-code="XX">Not this one</div>
<div class="prodCodes" data-prod-code="58">There</div>

How to check if an Object already exists in an Array before adding it?

I have this algorithme issue, I would like to check if an Object is already present in my Array before adding it.
I tried many different approaches (indexOf, filter...), and my last attempt is with an angular.foreach.
The problem is my $scope.newJoin remains always empty. I understood why, it's because the if is never read, because of the 0 size of my $scope.newJoin, but I don't know how to figure this out...
$scope.newJoinTMP is composed by : 6 Objects, within each a timePosted attribute (used for compare these different array Objects).
$scope.newJoin is an empty Array. I want to fill it with the Objects inside $scope.newJoinTMP but with the certainty to have once each Objects, and not twice the same ($scope.newJoinTMP can have duplicates Objects inside, but $scope.newJoin mustn't).
angular.forEach($scope.newJoinTMP, function(item)
{
angular.forEach($scope.newJoin, function(item2)
{
if (item.timePosted === item2.timePosted)
{
//snap.val().splice(snap.val().pop(item));
console.log("pop");
}
else
{
$scope.newJoin.push(item);
console.log("newJoin :", $scope.newJoin);
}
});
});
if(!$scope.newJoin.find(el=>item.timePosted===el.timePosted){
$scope.newJoin.push(item);
console.log("newJoin :", $scope.newJoin);
}
You dont want to push inside an forEach, as it will push multiple times...
There might be better ways to handle your particular situation but here's a fix for your particular code.
Replaced your inner for each with some which returns boolean for the presence of element and by that boolean value, deciding whether to add element or not
angular.forEach($scope.newJoinTMP, function(item)
{
var isItemPresent = $scope.newJoin.some(function(item2)
{
return item.timePosted === item2.timePosted;
//you dont need this conditional handling for each iteration.
/* if (item.timePosted === item2.timePosted)
{
//snap.val().splice(snap.val().pop(item));
console.log("pop");
}
else
{
$scope.newJoin.push(item);
console.log("newJoin :", $scope.newJoin);
} */
});
if( ! isItemPresent ) {
$scope.newJoin.push(item);
} else {
//do if it was present.
}
});
If you want to avoid the nested loop (forEach, some, indexOf, or whatever) you can use an auxiliar object. It will use more memory but you will spent less time.
let arr = [{ id: 0 }, { id:0 }, { id: 1}];
let aux = {};
const result = arr.reduce((result, el) => {
if (aux[el.id] === undefined) {
aux[el.id] = null;
return [el, ...result];
} else {
return result;
}
}, []);
console.log(result);
You can use reduce
$scope.newJoin = $scope.newJoinTMP.reduce(function(c, o, i) {
var contains = c.some(function(obj) {
return obj.timePosted == o.timePosted;
});
if (!contains) {
c.push(o);
}
return c;
}, []);
The problem with your current code is, if newJoin is empty, nothing will ever get added to it - and if it isnt empty, if the first iteration doesn't match the current item being iterated from newJoinTMP - you're pushing.

Compare Objects in Array and Remove Duplicate & Update - Javascript

I have an array of objects that presents as follows:
0: Object
ConsolidatedItem_catalogId: "080808"
ConsolidatedItem_catalogItem: "undefined"
ConsolidatedItem_cost: "0"
ConsolidatedItem_description: "Test Catalog Item"
ConsolidatedItem_imageFile: "27617647008728.jpg"
ConsolidatedItem_itemNumber: "1234"
ConsolidatedItem_quantity: "1"
ConsolidatedItem_source: "CAT"
ConsolidatedItem_status: "02"
ConsolidatedItem_umCode: "EA"
1: Object
ConsolidatedItem_catalogId: ""
ConsolidatedItem_catalogItem: "undefined"
ConsolidatedItem_cost: "0"
ConsolidatedItem_description: "ALARM,SHUTDOWN SYSTEM,AXIOM,XP3, 0-1500 PSIG, HIGH AND LOW PRES Testing"
ConsolidatedItem_imageFile: ""
ConsolidatedItem_itemNumber: "10008"
ConsolidatedItem_quantity: "1"
ConsolidatedItem_source: "INV"
ConsolidatedItem_status: "02"
ConsolidatedItem_umCode: "EA"
I'm trying to update and remove an object if it's added again, or update the object. Preferably update the object with the new value. My code is as follows:
var result = $.grep(finalObject, function(e) {
return e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber;
});
console.log(result);
if (result.length == 0) {
finalObject.push(o);
shoppingCounter = finalObject.length;
$('#numberShoppedItems').text(shoppingCounter);
console.log(finalObject);
} else if (result.length == 1) {
finalObject.filter(function(x){
result = x;
console.log(result);
return x == result.ConsolidatedItem_itemNumber;
});
} else {
alert('Multiples Found');
}
}
I've tried multiple ways of getting the exact object and manipulating the data, however they've all failed. I would prefer to update the object, say if CatalogItem_itemNumber held the same value, if the CatalogItem_quantity was different - add the CatalogItem_quantity values together and update the array of objects.
I don't need an exact answer, a nudge in the right direction would do wonders though. I've looked at several of the related questions over the past couple of hours but none of them seem to address the issue. If you know of a question that has an answer, feel free to just link that as well. I may have missed it.
No Underscore.js please
When you find the matching record, you may update it by using $.extend
$.extend(result[0], o)
This will update the object in finalObject array in-place.
Alternatively, if you want to use the filter, you will need to insert the new object in the array.
finalObject = finalObject.filter(function(x) {
return x !== result[0];
});
finalObject.push(o)
Here we are allowing all the records that are not not equal to result to be returned in the resultant array that is received in finalObject. In next line, we are adding the new record.
Solved in the following manner:
1.) Verify object is not empty.
2.) Use .some() on object to iterate through it.
3.) Check if the finalObject, which is now e, has a match for the key in my temporary object I assemble, o.
4.) Update the values that need updating and return true;
Note: Originally I was going to remove the object by its index and replace it with a new object. This too can work by using .splice() and getting the index of the current object in that array you're in.
Here is the updating version:
if (o.ConsolidatedItem_quantity != '') {
var result = $.grep(finalObject, function(e) {
return e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber;
});
if (result.length == 0) {...}
else {
finalObject.some(function (e) {
if(e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber){
var a;
a = +e.ConsolidatedItem_quantity + +o.ConsolidatedItem_quantity;
e.ConsolidatedItem_quantity = a.toString();
document.getElementById(o.ConsolidatedItem_itemNumber).value=a;
return true;
};
});
}
}

Categories