Dealing with type casted objects in jQuery

A bit of a noob to JavaScript OOP here. I have a native JavaScript object that I intend casting as an array and using it as an array but I can’t understand why it doesn’t work. I have a form like
<input type="text" id=input />

Then I have my jQuery like

var vars = {about: "about", bunny: "bunny", case: "case"};
$("#input").on("input", function(){
	vars = Array.prototype.filter.call(vars, function(b){
		console.log(b);
		return b.indexOf($(this).val()) != -1;
	});
});

It says “Array.prototype.filter called on null” and I can’t figure out why

When iterating over an array, it ignores the properties contained within it.

var vars = ["about", "case"];
vars.bunny = "bunny";
$("#input").on("input", function(){
  vars = Array.prototype.filter.call(vars, function(b){
		console.log(b);
		//return b.indexOf($(this).val()) != -1;
	});
});

The console shows just “about” and “case”.

What’s wrong with using an array?

I need the keys as well. Specifically, I need to be able to request for value by key instead of by value directly and JavaScript does not support associative arrays so I’m stuck with objects. Casting objects as arrays however does nothing when I attempt using the array methods forEach not filter. Why is this so and how do you suggest I access keys instead? For-in?

arbitrary objects miss the requirements for arrays. it’s that simple.

$.each()

My confusion is why this ^^^ does not treat it as an array. An object is an iterable data structure/type so ideally, it should be able to iterate and behave normally. I have used DOM objects extensively with the dozens of jQuery methods available and I’m just surprised this simple object to array casting is seemingly impossible in JavaScript.[quote=“Dormilich, post:4, topic:227790”]
$.each()
[/quote]

Will each let me return an object containing filtered off values as the jQuery filter method works different from the native JS filter method?

Using $.each(vars, function(b){ works, but you also have an index of 0 to deal with.

Let’s do this properly with the object keys instead.

var vars = {about: "about", bunny: "bunny", case: "case"};
$("#input").on("input", function(){
  var input = this;
  Object.keys(vars).forEach(function(b){
    if (b.indexOf(input.value) === -1) {
      delete vars[b];
    }
  });
  console.log(vars);
});
1 Like

objects do behave normaly when iterated. it’s just that array methods are not iterators. iterable is not the same as an array, an array is way more restricted than an iterable. and what is “normal” in JS is defined in the specification, not by us.

^^^ :scream: :scream::scream::scream:

Yes, I agree. Having the forEach function reach out and change the original object is a bad idea.

Instead, we’ll reduce the keys and add to them to a new object. That way we can assign the new object to whatever we want.

var vars = {about: "about", bunny: "bunny", case: "case"};
$("#input").on("input", function() {
  var input = this;
  vars = Object.keys(vars).reduce(function(callback, key) {
    if (key.indexOf(input.value) > -1) {
      callback[key] = vars[key];
    }
    return callback;
  }, {});
  console.log(vars);
});

[quote=“Paul_Wilkins, post:9, topic:227790, full:true”]
Instead, we’ll reduce the keys and add to them to a new object. That way we can assign the new object to whatever we want.[/quote]

We can improve that code further by pulling the function out to a separate wrapper:

var vars = {about: "about", bunny: "bunny", case: "case"};

function keyContainsValue(value, sourceObj) {
  return function reduceToKeysMatchingValue(callback, key) {
    if (key.indexOf(value) > -1) {
      callback[key] = sourceObj[key];
    }
    return callback;
  };
}
$("#input").on("input", function() {
  var input = this;
  var result = Object.keys(vars).reduce(keyContainsValue(input.value, vars), {});
  console.log(result);
});

You can explore this at https://jsfiddle.net/91tuz5rh/

1 Like

While I truly appreciate your contributions here, I will solicit your code improvement skills on my other AJAX thread just created on this board not too long ago. Thank you.

Sorry but things don’t work that way around here. If someone is both willing and capable they will participate. I do not wish to be coerced.

Thanks all the same for your time :slight_smile:

I know this is an old topic but for myself and for anyone else who might need this code, I hope to explain better so even though it works, you can know why it does:

I hope it is clearer now and explaining it this way makes it stick for me too.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.