javascript only remove first match in array in loop - javascript

I have an array of Exclusions like below:
Exclusions: [ID:"233242", Loc:"West", ID:"322234" , Loc:"South"]
I also Object nested with an array of objects that could look something like
Schools : [ O: [ ID:"233242" ] , 1:[ ID:"233242"] , 2: [ID :"954944"] ]
I need to delete from the schools object any matching array indices with the same ID but only for the first match. That means element 0 should be removed, but element 1 should still be there. What's the best way to fix my loop:
$.each(Exclusions, function (index, value) {
var loc = value.Loc;
var ID = value.ID;
Object.keys(Schools.District.Pack[loc]).forEach(function (key) {
//i need to scan through the entire object
if (Schools.District.Pack[loc].ID === ID) {
//remove the first match now stop looking
Schools.District.Pack[loc].splice(key, 1);
//break ; incorrect
}
});
});

I'd say having another lookup array for removed IDs, and you'll need something like this
var Exclusions = [{ID:"233242", Loc:"West"}, {ID:"322234" , Loc:"South"}];
var Schools = [{ ID:"233242" } ,{ ID:"233242"} , {ID :"954944"} ];
var removedKeys = [];
$.each(Exclusions, function (index, value) {
var loc = value.Loc;
var ID = value.ID;
Object.keys(Schools).forEach(function (key) {
//i need to scan through the entire object
if ((Schools[key].ID === ID) && (removedKeys.indexOf(ID) == -1)) {
removedKeys.push(ID);
//remove the first match now stop looking
delete Schools[key];
}
});
});
console.log(removedKeys);
console.log(Schools);
Hope this would help
fiddle

Related

How to add an item to a list by replacing the earlier one. In Javascript

I have a list will a list but it only has one item I need to be able to replace that with a new one. But there should one be one.
Because there is a condition involve I need to be able to create an variable if something there or not but I found the list to be easier so how can I replace an item in a list with a new one
let subject_reply = [];
if (email.subject.startsWith("Re:") == true) {
subject_reply.push(email.subject);
}else{
subject_reply.push(`Re: ${email.subject}`);
}
Maybe this helps you, to replace an item of an array you can use splice method, this code says: replace item at index 1, delete that item and insert 'Boxer'.
var dogs = ['Bulldog', 'Beagle', 'Labrador'];
dogs.splice(1, 1, 'Boxer');
console.log(dogs);
I'm not sure if that is what you asked for, it's an array that holds one item only, by clearing the array when we click on the button and it takes the value of the input and then pushing it to the array by making it the only value.
If the `value` starts with *Re:*{
Push as it is.
} else {
Push: "Re: value"
}
var myInput = document.getElementById('myInput');
var myBtn = document.getElementById('myBtn');
let subject_reply = [];
myBtn.addEventListener('click', () => {
subject_reply = [];
var textValue = myInput.value;
if (textValue.startsWith("Re:") == true) {
subject_reply.push(textValue);
} else{
subject_reply.push(`Re: ${textValue}`);
}
console.log(subject_reply);
});
<input type='text' id='myInput'>
<button id='myBtn'>Click</button>
It's difficult to answer a poorly-worded question. As I understand it, one of these is the answer you seek:
subject_reply.push("Re: " + email.subject.replace(/^Re:\s?/, ""));
OR
subject_reply[0] = "Re: " + email.subject.replace(/^Re:\s?/, "");
I understand you want to replace a string value in an array.
For this, Function "Replace()" will help. In this problem specific to you, "EmailREAdder()" will help you adding "RE:" at the start of a string which does not contain "RE:".
/* Function for replacing an item */
const Replace = (arr,oldValue, newValue) => arr.splice(arr.indexOf(oldValue), 1, newValue);
/* Setting all without "RE:" to RE*/
const EmailREAdder = arr => {
arr.map(item => {
if(!item.match(/RE:/)){
Replace(arr, item, `RE: ${item}`);
}
});
}
/* code */
let users = [
"RE: Farman Ali",
"Usman",
"Fraz"
];
console.log(users);
EmailREAdder(users);
console.log(users);

Trouble removing duplicates from list

//get email from test area
var emailList = document.getElementById("emailTextarea").value;
var emailListArray = emailList.split("\n");
//Remove yahoo and duplicates from the list
var usernamesArray = emailListArray.map(function(val, index, arr) {
return val.slice(0, val.indexOf('yahoo.com'));
});
Assuming:
emailListArray = ['123#gmail.com','123#yahoo.com','123#gmail.com','123#hotmail.com']
You can do something like this:
var usernamesArray = [];
emailListArray.forEach(function(item) {
if(usernamesArray.indexOf(item) < 0 && item.indexOf('yahoo.com') < 0) {
usernamesArray.push(item);
}
});
First condition checks if the element in turn is not already in the array of results, second condition checks if the element doesn't contain the substring yahoo.com, if both are true, the element is added to the results.
After that, usernamesArray should have:
[ '123#gmail.com', '123#hotmail.com' ]

FInd object in array by value and update entire object

I have a list of objects and sometimes I receive an update from the API for one of those objects and what I need to do is to find the object with the id of the one to update and update the entire object...
I was trying to avoid a for loop because the list could be very very long.
So what I was trying to use is $.grep but it doesn't seem to work as expected.
Here is what I tried so far:
// item is the response data from the API
var item = res.item;
var index = $.grep(arrayOfItems, function (e, i) {
if (e.id === item.id) {
return i;
}
});
arrayOfItems[index] = item;
the item is not updated unfortunately...
If it's speed you're after, especially with a long list, you may consider indexing your list by id when you first retrieve it, making updates later quicker than having to loop the entire array to find an index.
To demonstrate, assume you have retrieved an array of objects
var data = [
{id:1,data:'hello'},
{id:2,data:'world'},
{id:3,data:'foo'},
{id:4,data:'bar'}];
now create an object which represents your data where the property is the Id (object properties cannot start with a number, so if id is numeric, prefix it) and the value is the index back into the original array. So, the above data would be transformed to
var dataIndex = {
id1:0,
id2:1,
id3:2,
id4:3
};
This can be done trivially with a function
function indexDataById(data)
{
var index = {};
$.each(data, function(e,i){
index['id' + e.id] = i;
});
return index;
}
var dataIndex = indexDataById(data);
Now, when it comes to your update, you can find the index instantly using the id
var updateId = 2;
var elementIdx = dataIndex ['id' + updateId];
data[elementIdx] = myNewData;
The one complication is that you need to go back and update the index if the id of the new data has changed:
var updateId = 2;
var elementIdx = dataIndex [`id` + updateId];
data[elementIdx] = myNewData;
delete dataIndex[elementIdx]
dataIndex['id' + myNewData.id] = elementIdx;
This should be easy enough to handle atomically with your update.
$.map and $.grep return both an array so you will never get the index.
Inside $.map or $.grep function you need to return true or false based
on your filter logic. They re not useful in your case.
if your structure is not ordered you can only loop trough it and stop the loop when you find your element... like that:
var item = res.item;
var index = "";
$.each(arrayOfItems, function(i,v){
if(item.id == v.id){
index = i;
return true;
}
});
arrayOfItems[index] = item;
if you wanna order your structure before loop use this:
arrayOfItems.sort(function(a, b) {
return a.id > b.id;
});
i ve made a fiddle with an example https://jsfiddle.net/L08rk0u3/
try this way using $.grep
var arrList = [
{name :11,id :11},{name :12,id :12},{name :111,id :111},
{name :13,id :13},{name :15,id :15},{name :11,id :11},
{name :41,id :41},{name :31,id :31},{name :81,id :81},
{name :91,id :91},{name :13,id :13},{name :17,id :17},
{name :1111,id :1111}
]
console.log(arrList);
var respItem ={name :1111000,id:1111};
var intSearchedIndex;
$.grep(arrList,function(oneItem,index){
if(respItem.id==oneItem.id){
return intSearchedIndex = index;
}
})
arrList[intSearchedIndex] =respItem;
console.log(intSearchedIndex,arrList);
Try with map method like this.
Code snippets:
// item is the response data from the API
var item = res.item;
var index = $.map(arrayOfItems, function (e, i) {
if (e.id === item.id) {
return i;
}
});
if(index.length)
arrayOfItems[index[0]] = item;
Update:
arrayOfItems[index] = item;
This will work if index array has an single element. See fiddle
But,
arrayOfItems[index[0]] = item;
This is the appropriate way since it is an array.

jQuery get json data, match the ids, then append the custom field value

I am trying to retrieve json data from zendesk, then compare the value of the ids in each ticket that is retrieved from the server with the id inside my table data. If the ids match, then I want to retrieve the custom field value inside the ticket with the matching id, and append it to the table data's that i have named with the product id. The idea is to target each "td/td",and automatically insert the custom field(product id) value when a new "td/td" tag is created. Please help :) The Object 99 at the top is the ticket, the id :175 is the id I am trying to match. the custom_field array[10] value is what I want to append and display. The issue I am having is that the data is not displaying after I append it. I think this has something to do with how I am accessing the data, comparing the ids, then appending the custom field. The array value is returning a -1 instead of comparing the IDs. This is the problem.
//first lets get some json data!
var getjson = $.getJSON("/api/v2/tickets.json)",function (result) {
$.each(result, function(i, field) {
console.log('data',field);
// now lets take the text id for each td and assign it as the id.
$(".sort > tr > td:nth-child(1)").each(function(){
var textid = $(this).text();
$(this).attr('id', textid);
// if the ids match, give me the value of the custom field that is inside the array of the matching id.
var arr = [field];
var arrayvalues = $.inArray('id', arr);
if ($(this).attr('id') == arrayvalues){
/* if the ids match, give me the value of the
custom field that is inside the array of the matching id. */
var returns = $.inArray('value',arr.custom_fields[i]);
// now for each td lets append the value of the custom field.
$(".sort > tr > td:nth-child(7)").each(function () {
$(this).append(returns);
$(this).attr('id','product');
})
}
})
});
See $.inArray usage described at documentation
jQuery.inArray( value, array [, fromIndex ] )
value
Type: Anything The value to search for.
array
Type: Array An array through which to
search. fromIndex Type: Number The index of the array at which to
begin the search. The default is 0, which will search the whole array.
Note, also $.inArray()
Returns: Number
Not certain about return value from $.getJSON ? full json not appear at original post ? , though see
$.getJSON("/api/v2/tickets.json}"
right bracket before closing double-quotation mark at url ?
Try changing js at
var arrayvalues = $.inArray(field).id;
and
var returns = return $.inArray(field).custom_fields('value');
to usage described at documentation, e.g.,
var arr = ["a", "b", "c"];
console.log(
$.inArray("a", arr) // `0`
, $.inArray("b", arr) !== -1 // `true`
, $.inArray("c", arr) === 3 // `false`
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
I figured it out after days of knocking my head against the wall. The following code works perfectly.
var Obj1 = {};
var Obj2 = {};
var Obj3 = {};
var urlstring = "/api/v2/tickets/"+id+".json)";
$.getJSON(urlstring,function (result) {
$.each(result, function(i, value) {
Obj1[result[i].id] = result[i].fields[10].value;
Obj2[result[i].id] = result[i].fields[13].value;
Obj3[result[i].id] = result[i].fields[7].value;
console.log('Obj1', Obj1);
console.log('Obj2', Obj2);
console.log('Obj3', Obj3);
});
$.each(Obj1, function(key, element) {
$(".sort > tr").each(function(){
if($(this).attr('id') == key){
$(this).children('td:nth-child(7)').append(element);
}
});//end tr each
}); //end obj1 each
$.each(Obj2, function(key, element) {
$(".sort > tr").each(function(){
if($(this).attr('id') == key){
$(this).children('td:nth-child(8)').append(element);
}
});//end tr each
}); //end obj2 each
$.each(Obj3, function(key, element) {
$(".sort > tr").each(function(){
if($(this).attr('id') == key){
$(this).children('td:nth-child(6)').append(element);
}
});//end tr each
}); //end obj3 each
});//end json

Javascript : Select Element in URL with multiple instance of the same element

i need to retrieve a value from an URL in JS, my problem is in this url, the element is repeated at least twice with different value. What i need is the last one.
Example :
http://randomsite.com/index.php?element1=random1&element2=random2&element1=random3
and what i want is "random3" and NOT "random1"
I've tried url.match(/.(\&|\?)element1=(.?)\&/)[2];
But it always gives me the first one :(
I don't have the possibility to change how the url is written as this is for a browser extension.
var ws = "http://randomsite.com/index.php?element1=random1&element2=random2&element1=random3",
input = ws.split("?")[1].split("&"),
dataset = {},
val_to_find = "element1";
for ( var item in input){
var d = input[item].split("=");
if (!dataset[d[0]]){ dataset[d[0]] = new Array(); dataset[d[0]].push(d[1]); }
else{
dataset[d[0]].push(d[1]);
}
}
console.log("item: ", dataset[val_to_find][dataset[val_to_find].length -1]);
return dataset[val_to_find][dataset[val_to_find].length -1];
http://jsfiddle.net/wMuHW/
Take the minimum value (other than -1) from urlString.lastIndexOf("&element1=") and urlString.lastIndexOf("?element1="), then use urlString.substring.
Or alternately, split the string up:
var parts = urlString.split(/[?&]/);
...which will give you:
[
"http://randomsite.com/index.php",
"element1=random1",
"element2=random2",
"element1=random3"
]
...then start looping from the end of the array finding the first entry that starts with element= and grabbing the bit after the = (again with substring).
You could;
for (var result, match, re = /[&?]element1=(.+?)(\&|$)/g; match = re.exec(url);) {
result = match[1];
}
alert(result);
Id try keeping a nested array of duplicate elements
function parseQueryString() {
var elements = {},
query = window.location.search.substring(1),
vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('='),
key = decodeURIComponent(pair[0]),
value = decodeURIComponent(pair[1]);
if (elements.hasOwnProperty(key)) {
elements[key].push(value);
}
else {
elements[key] = [value];
}
}
}
Used on: www.example.com?element1=hello&element2=test&element1=more
Would give you the object:
{
element1: [
"hello",
"more"
],
element2:[
"test"
]
}

Categories

Resources