1

I want to be able to match a specific string (full match not partial match) and then delete that specific item from the array if it matches.

I have some code but it doesn't seem to be deleting the item from the array. I do wish for it to change the original array and not create a new array so I am not using filter.

How can I go about accomplishing this?

Current Code:

let recentSearches = [
  { name: "Chicago, IL" },
  { name: "Orlando, FL" },
  { name: "Dallas, TX" }
];

let stringToRemove = "Dallas, TX";

recentSearches.some(recent => {
  if (recent.name === stringToRemove) {
    const index = recentSearches.indexOf(stringToRemove);

    if (index !== -1) { //Never goes into this if
      recentSearches.splice(index, 1);
      console.log(recentSearches);
    }
  }
});

console.log(recentSearches);

JS Fiddle: enter link description here

1
  • It's not an array of strings, it's an array of objects. Commented Jul 27, 2021 at 21:03

6 Answers 6

2

If you don't mind the output being a different array, use filter:

const filteredSearches = recentSearches.filter((recent) => recent.name !== stringToRemove);

If you need to modify the array in-place, you should visit the elements in reverse order (in case of multiple matches, which causes indices to shift) like so:

for (let i = recentSearches.length-1; i >= 0; i--) {
  if (recentSearches[i].name === stringToRemove) {
    recentSearches.splice(i, 1);
  }
}

The problem with your code is you use recentSearches.indexOf, but recentSearches isn't an array of strings, so nothing matches. You could modify your code as follows, but it won't work correctly in case of multiple mathces:

recentSearches.forEach((recent, index) => {
  if (recent.name === stringToRemove) {
    recentSearches.splice(index, 1);
  }
});

Alternatively, you could use findIndex (as suggested in other comments and answers) as follows:

let index;
while (0 <= (index = recentSearches.findIndex((recent) => recent.name === stringToRemove)) {
  recentSearches.splice(index, 1);
}
Sign up to request clarification or add additional context in comments.

Comments

2

indexOf() is for finding exact matches. Since your array contains objects, they'll never be equal to stringToRemove.

Use findIndex() to get the index of an array element using a function that an compare the name property.

There's also no need for using some().

let recentSearches = [{
    name: "Chicago, IL"
  },
  {
    name: "Orlando, FL"
  },
  {
    name: "Dallas, TX"
  }
];

let stringToRemove = "Dallas, TX";

const index = recentSearches.findIndex(({
  name
}) => name == stringToRemove);
if (index !== -1) { //Never goes into this if
  recentSearches.splice(index, 1);
}

console.log(recentSearches);

Comments

1

Another version of the findIndex, instead of using while, you could use for, a slight advantage here is that the index is then locally scoped inside the the for, were with a while loop you have the extra scope of the index, you could close the the scope of a let by doing { let index; while() {..}} but the for loop avoids that without using {}.

let recentSearches = [
    {name: "Chicago, IL"},
    {name: "Orlando, FL"},
    {name: "Dallas, TX"}
];
  
let stringToRemove = "Dallas, TX";

for (let index; index = recentSearches.findIndex(
  search => search.name === stringToRemove), index > -1;) 
    recentSearches.splice(index, 1);

console.log(recentSearches);

Comments

1

The JSON search is done wrongly.

I have added the perfect code to complete your requirement. Find all instances and delete them with a while loop. This will ensure duplicate search terms are also removed if any.

let recentSearches = [
    {name: "Chicago, IL"},
    {name: "Orlando, FL"},
    {name: "Dallas, TX"}
];
  
let stringToRemove = "Dallas, TX";

while (recentSearches.findIndex(search => search.name === stringToRemove) > -1) {
    const index = recentSearches.findIndex(search => search.name === stringToRemove);
    recentSearches.splice(index, 1);
}

console.log(recentSearches);

2 Comments

@PA-GW ensure to add a while block to make sure the code is corner-case covered.
Oh sorry, the author corrected it now. Initially, it was like let stringToRemove = "Dallax, TX";
0

You can use findindex. Store it in a variable. And use splice

Comments

0

You can use this code:

Array.prototype._arraycopy =  function(src, srcPos, dest, destPos, length) {
  while ((--length) >= 0) {
    dest[destPos++] = src[srcPos++];
  }
};

Array.prototype._fastRemove = function(es, i) {
  let newSize;
  if ((newSize = this.length - 1) > i) 
    this._arraycopy(es, i + 1, es, i, newSize - i);
  es[this.length = newSize] = null;
  this.length = newSize;
}

Array.prototype.__removeAt = function(index) {
  // Objects.checkIndex(index, size);
    const es = this;

    const oldValue =es[index];
    this._fastRemove(es, index);
    return oldValue;
}

Array.prototype.__removeAtValue = function(o) {
  const es = this;
  const size = this.size;
  let i = 0;
  (function() {
    if (o == null) {
        for (; i < size; i++)
            if (es[i] == null)
                return true;
    } else {
        for (; i < size; i++)
            if (Object.is(o, es[i]))
                return true;
    }
    return false;
  })()
  this._fastRemove(es, i);
  return true;
}

Array.prototype.remove = function(index) {
  return this.__removeAt(index)

}

Array.prototype.removeObj = function(obj) {
  return this.__removeAtValue(obj);
}

const arr = [1, 3, 4, 5, 10];
console.log(arr);
const rem = arr.remove(1)
console.log({ arr, rem });

const objs = [{ id: 1, name: "Hello" }, { id: 2, name: "Arrow" }, { id: 3, name: "Star" }]
console.log(objs);
const deleted = objs.removeObj({ id: 2, name: "Arrow" });
console.log({ objs, deleted })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.