following adds items to array:
var arrayOptions = [];
function AddToFilterOptionList(mode) {
arrayOptions.push(mode);
}
remove item from array:
function RemoveFromFilterOptionList(mode) {
var index = arrayOptions.indexOf(mode);
if (index !== -1) {
arrayOptions.splice(index, 1);
}}
for example if i call
AddToFilterOptionList('APPLE') - APPLE should be added to array.
If i again call
AddToFilterOptionList('APPLE+FRUIT') - it should remove the the item 'APPLE' from array arrayOptions and should add APPLE+FRUIT
Any time only one word that starts with APPLE can be in array.
How to find the word like 'APPLE' in javascript.
I tried with Match() which returns the matching word. IndexOf() returns 1 only if whole word is match but not start of word.
Cycle through the Array and then use the startsWith method.
void AddToFilterOptionList(String mode) {
for (i=0; i<arrayOptions.length; i++) {
if (mode.startsWith(arrayOptions[i] == 1)) {
array[i] = mode;
return; // found, so return
}
}
arrayOptions.push(mode); // should only get here if string did not exist.
}
You need to split by + characted and then loop over produced array to add/remove all items:
var arrayOptions = [];
function AddToFilterOptionList(mode) {
mode.split(/\+/g).forEach(function(el) {
var index = arrayOptions.indexOf(el);
if (index !== -1) {
arrayOptions.splice(index, 1);
}
else {
arrayOptions.push(el);
}
});
}
function RemoveFromFilterOptionList(mode) {
var index = arrayOptions.indexOf(mode);
if (index !== -1) {
arrayOptions.splice(index, 1);
}
}
AddToFilterOptionList('APPLE');
document.write('<p>' + arrayOptions); // expect: APPLE
AddToFilterOptionList('APPLE+FRUIT');
document.write('<p>' + arrayOptions); // expect: FRUIT
AddToFilterOptionList('APPLE+FRUIT+CARROT');
document.write('<p>' + arrayOptions); // expect: APPLE,CARROT
This will work assuming the 'this+that' pattern is consistent, and that we only care about the starting item.
http://jsbin.com/gefasuqinu/1/edit?js,console
var arr = [];
function remove(item) {
var f = item.split('+')[0];
for (var i = 0, e = arr.length; i < e; i++) {
if (arr[i].split('+')[0] === f) {
arr.splice(i, 1);
break;
}
}
}
function add(item) {
remove(item);
arr.push(item);
}
UPDATE:
function add (array, fruits) {
var firstFruit = fruits.split('+')[0]
var secondFruit = fruits.split('+')[1]
var found = false
var output = []
output = array.map(function (item) {
if (item.indexOf(firstFruit) > -1) {
found = true
return fruits
}
else return item
})
if (! found) {
array.push(fruits)
}
return output
}
var fruits = []
add(fruits, 'APPLE')
fruits = add(fruits, 'APPLE+GRAPE')
console.log(fruits[0]) // 'APPLE+GRAPE'
fruits = add(fruits, 'APPLE')
console.log(fruits[0]) // 'APPLE'
Try this, the code is not optimised though :P
<html>
<head>
<script src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
var itemList = [];
function addItem()
{
var item = $('#item').val();
if(item != '' || item != 'undefined')
{
if(itemList.length == 0)
itemList.push(item);
else
{
for(i=0;i<itemList.length;i++)
{
var splittedInputItems = [];
splittedInputItems = item.split("+");
var splittedListItems = [];
splittedListItems = itemList[i].split("+");
if(splittedListItems[0] == splittedInputItems[0])
{
itemList.splice(i,1);
itemList.push(item);
return;
}
}
itemList.push(item);
}
}
}
</script>
</head>
<body>
<input id="item" type = "text"/>
<input type = "button" value="Add" onclick="addItem()">
</body>
</html>
let items = [1, 2, 3, 2, 4, 5, 2, 7];
let item = 2;
for (let i = 0; i < items.length; i++) {
if (items[i] === item) {
items.splice(i, 1);
i = i - 1;
}
}
If you want to remove the element '2' from items array, it is a way.
Related
Would like to create an array with number of matches for specific regexs:
So if january was found 5 times , feb 3 the table would be:
monthFound=[5,3......]
function findMonth(){
var fpath='log.txt';
var monthFound=[]
fs.readFileSync(fpath).toString().split('\n').forEach(function(line)
{
var regExpressions1=[/-jan-/,/-feb-/,/-mar-/,/-apr-/,/-may-/,/-jun-/,/-jul-/,/-aug/,/-sep-/,/-oct-/,/-nov/,/-dec-/];
for (var i = 0; i<regExpressions1.length;i++)
{
var idx = line.match(regExpressions1[i]);
if (idx !== null) {
y++;
}
}
});
}
This will return an array with each month match count:
fs.readFileSync(fpath).toString().split('\n').reduce((count, str) => {
['-jan-','-feb-','-mar-','-apr-','-may-','-jun-','-jul-','-aug-','-sep-','-oct-','-nov-','-dec-'].forEach((month, idx) => {
const match = (str.match(new RegExp(month, 'g')) || []).length;
if (count[idx]) {
count[idx] += match;
} else {
count[idx] = match;
}
});
return count;
}, []);
Use this :
function findMonth(){
var fpath='log.txt';
var monthFound=[]
fs.readFileSync(fpath).toString().split('\n').forEach(function(line) {
var regExpressions1=["-jan-","-feb-","-mar-","-apr-","-may-","-jun-","-jul-","-aug-","-sep-","-oct-","-nov-","-dec-"];
for (var i = 0; i<regExpressions1.length;i++) {
var idx = line.match(new RegExp(Expressions1[i]));
monthFound[i] === idx.length
}
});
}
Bit of a weird one. Am using the following code build an array from a json object to make it easier to reference later in the code. However it would appear that when the last item of each array is created, rather than adding a new item, the Key of the item appears as the length of the array.
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
for (var perf_no in obj.Extras) {
if (extras[perf_no] == undefined) {
var arr = new Array();
for (var extra in obj.Extras[perf_no]) {
if (arr[extra] == undefined) {
arr[extra] = obj.Extras[perf_no][extra];
}
}
extras[perf_no] = arr;
}
}
break;
}
}
}
The resulting array appears as below:
Any ideas what's going on here?
Edit:
Sample of Json below
{"Extras":{"32516":{"24186":"Example text"},"32515":{"24186":"Example text"},"32514":{"24186":"Example text"},"32512":{"24186":"Example text"},"32513":{"24186":"Example text"},"32511":{"24186":"Example text"},"32510":{"24186":"Example text"},"32509":{"24186":"Example text"},"32507":{"24186":"Example text"},"32503":{"24186":"Example text"},"32506":{"24186":"Example text"},"32505":{"24186":"Example text"},"32508":{"24186":"Example text"},"32502":{},"32497":{}}}
What's going on hear is that you are using for..in to iterate over an array, which is a no-no because it iterates properties that are not the array elements (such as the .length property). Instead, use Array#forEach:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
obj.Extras.forEach(function (item, idx) {
if (typeof extras[idx] === 'undefined') {
var arr = new Array();
item.forEach(function (item2, idx2) {
if (typeof arr[idx2] === 'undefined') {
arr[idx2] = item2;
}
});
extras[idx] = arr;
}
});
break;
}
}
}
The innermost loop is pretty pointless and can be replaced with Array#slice:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
obj.Extras.forEach(function (item, idx) {
if (typeof extras[idx] === 'undefined') {
extras[idx] = item.slice();
}
});
break;
}
}
}
The next inner loop can be replaced with Array#map and two if statements can be combined:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null&& obj.Extras != null) {
extras = obj.Extras.map(function (item) {
return item.slice();
});
break;
}
}
In fact, most of this code can be simplified:
function findLastElement(arr) {
for (var i = arr.length - 1; i >= 0; i -= 1) {
if (arr[i] != null && arr[i].Extras != null) { return arr[i]; }
}
}
perfsJson = $.parseJSON(result);
var lastElement = findLastElement(perfsJson);
var extras = lastElement
? lastElement.Extras.map(function (item) { return item.slice(); })
: [];
So, I'm trying to delete from an array if it's element value isn't equal to a value that I specified:
Code: http://pastebin.com/hUc3mVLv
$scope.enablePVR = function()
{
for (i = 0; i < $scope.new_epg.length; i++) {
start_time = convert_time($scope.new_epg[i].start);
$scope.new_epg[i].title = $scope.new_epg[i].title.replace(/<(?:.|\n)*?>/gm, '');
$scope.new_epg[i].description = "";
$scope.new_epg[i].time = start_time;
}
archiveEPG = [];
for(var i=0; i<archiveEPG.length; i++) {
var e = document.getElementById("dateSelect");
if($scope.new_epg[i].start.split(" ")[0] == e[e.selectedIndex].value) {
archiveEPG[archiveEPG.length+1] = $scope.new_epg[i];
}
}
document.getElementById("dateSelect").remove(0);
$scope.get_epg(null, true, archiveEPG);
}
.remove(0) isn't valid you can add this function to make it valid tho :
Array.prototype.remove = function(index) {
return this.splice(index, 1); // The second parameter is the number of elements to remove.
}
I have an array of objects. Every object in the array has an id and an item property that is an array containing other object. I need to be able to find an element in an array by id. Here is a sample of what I have done so far, but the recursive function is always returning undefined.
How can I quit the function and return the item when I have called the function recursively several times?
$(function () {
var treeDataSource = [{
id: 1,
Name: "Test1",
items: [{
id: 2,
Name: "Test2",
items: [{
id: 3,
Name: "Test3"
}]
}]
}];
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems && subMenuItems.length > 0) {
for (var i = 0; i < subMenuItems.length; i++) {
var item;
if (subMenuItems[i].Id == id) {
item = subMenuItems[i];
return item;
};
getSubMenuItem(subMenuItems[i].items, id);
};
};
};
var searchedItem = getSubMenuItem(treeDataSource, 3);
alert(searchedItem.id);
});
jsFiddle
You should replace
getSubMenuItem(subMenuItems[i].items, id);
with
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
in order to return the element when it is found.
And be careful with the name of the properties, javascript is case sensitive, so you must also replace
if (subMenuItems[i].Id == id) {
with
if (subMenuItems[i].id == id) {
Demonstration
Final (cleaned) code :
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems) {
for (var i = 0; i < subMenuItems.length; i++) {
if (subMenuItems[i].id == id) {
return subMenuItems[i];
}
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
}
}
};
I know its late but here is a more generic approach
Array.prototype.findRecursive = function(predicate, childrenPropertyName){
if(!childrenPropertyName){
throw "findRecursive requires parameter `childrenPropertyName`";
}
let array = [];
array = this;
let initialFind = array.find(predicate);
let elementsWithChildren = array.filter(x=>x[childrenPropertyName]);
if(initialFind){
return initialFind;
}else if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childrenPropertyName]);
});
return childElements.findRecursive(predicate, childrenPropertyName);
}else{
return undefined;
}
}
to use it:
var array = [<lets say an array of students who has their own students>];
var joe = array.findRecursive(x=>x.Name=="Joe", "students");
and if you want filter instead of find
Array.prototype.filterRecursive = function(predicate, childProperty){
let filterResults = [];
let filterAndPushResults = (arrayToFilter)=>{
let elementsWithChildren = arrayToFilter.filter(x=>x[childProperty]);
let filtered = arrayToFilter.filter(predicate);
filterResults.push(...filtered);
if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childProperty]);
});
filterAndPushResults(childElements);
}
};
filterAndPushResults(this);
return filterResults;
}
I have an array like below
var colorArray = ["#a", "#b", "#c", "#d", "#e"];
From this I will generate a map like this
function initilizeColorMap(){
for(var i = 0 ;i <colorArray.length ;i++){
colorTrackingMap[i] = {value: colorArray [i],state:"unused"};
}
}
Hopw i can iterate through the map when i need a color (next color from the map ) by checking the state in javascript..?
You can have a method that will return the next color. Check out this jsfiddle : http://jsfiddle.net/QYWDb/
var colorArray = ["#a", "#b", "#c", "#d", "#e"];
var colorTrackingMap = [];
var currentIndex = -1;
for(var i = 0 ;i <colorArray.length ;i++){
colorTrackingMap[i] = {value: colorArray [i],state:"unused"};
}
function getNextColor() {
if (currentIndex > colorTrackingMap.length)
currentIndex = 0;
else
currentIndex++;
while ( colorTrackingMap[currentIndex] !== undefined &&
colorTrackingMap[currentIndex].state !== "unused" ) {
currentIndex++;
}
if ( colorTrackingMap[currentIndex] )
return colorTrackingMap[currentIndex].value;
else
return "No color available";
}
If you need color according to given index you don't have to iterate, use such code:
var currentIndex = 0;
function Next() {
var tracking = colorTrackingMap[currentIndex];
alert("color: " + tracking.value + ", state: " + tracking.state);
currentIndex++;
if (currentIndex >= colorTrackingMap.length)
currentIndex = 0;
}
Live test case.
If you mean searching the array for item with specific value, just use ordinary loop:
function Find() {
var color = document.getElementById("color").value;
var state = "";
for (var i = 0; i < colorTrackingMap.length; i++) {
if (colorTrackingMap[i].value.toLowerCase() === color) {
state = colorTrackingMap[i].state;
break;
}
}
if (state.length == 0) {
alert("color isn't mapped");
} else {
alert("state: " + state);
}
}
You can also pass the color as function argument, this is just for sake of example.
Updated test case.
You could use something like this:
var ColourMap = function (arr) {
var _map = [],
out = [],
i,
len;
// Set up the colour map straight away
for (i = 0, len = arr.length; i < len; i++) {
_map.push({
value: arr[i],
state: "unused"
});
}
return {
get_next: function () {
var i,
len,
next;
for (i = 0, len = _map.length; i < len; i++) {
if (_map[i].state === "unused") {
next = _map[i];
break;
}
}
return next;
}
}
};
And then use something like:
var m = new ColourMap(["#a", "#b", "#c", "#d", "#e"]);
m.get_next(); // get the next available element
Here's a working example.