skip to Main Content

From the answer of Why does a string index in an array not increase the ‘length’?, I found out that arrays can have both value and properties.

For example in the following code:

var array = [];
array['test1'] = 'property 1';
array['test2'] = 'property 1';
array[0] = 'value 1';
array[1] = 'value 2';

Second and third line create property.

Fourth and fifth line create value.

I can get the values using:

array.forEach((value) => {
    console.log(value);
});

How can I get only the properties?

3

Answers


  1. You can use it

    var array = [];
    array['test1'] = 'property 1';
    array['test2'] = 'property 1';
    array[0] = 'value 1';
    array[1] = 'value 2';
    
    Object.keys(array).forEach((key)=>{
      if(isNaN(+key)){
        console.log(array[key])
      }
    })
    Login or Signup to reply.
  2. Second and third line create property.

    Fourth and fifth line create value.

    No. All of those lines create a property and assigns a value to it.

    The only difference is that some of those property names are integers.

    How can I get only the properties?

    If you want to use properties that are not numbers then do not use an array.

    The purpose of an array is to store a set of values in an order. It does this using numeric property names. It has lots of special features specifically for handling numeric property names.

    Use a regular object instead. You can convert it to an array you are iterate over with Object.entries, and filter out selected properties based on their name if you like.

    const object = {};
    object['test1'] = 'property 1';
    object['test2'] = 'property 1';
    object[0] = 'value 1';
    object[1] = 'value 2';
    
    const logger = ([name, value]) => console.log(`${name} is ${value}`);
    
    Object.entries(object).forEach(logger);
    
    console.log("-------");
    
    Object.entries(object).filter(([name]) => !/^d+$/.test(name)).forEach(logger);
    Login or Signup to reply.
  3. You can use a couple of conditions to filter out those you don’t need:

    function* nonNumericProperties(object) {
      for (const key in object) {
        // Own keys only.
        if (!Object.hasOwn(object, key)) {
          continue;
        }
        
        // Filter out non-negative integers.
        // Keys like '001' are valid.
        if (/^(?:[1-9]d*|0)$/.test(key)) {
          
          // An array's size is capped at 2 ** 32 - 2,
          // which means integers greater than that
          // are not indices.
          // https://stackoverflow.com/a/6155063
          const parsedKey = Number(key);
          if (parsedKey <= 2 ** 32 - 2) {
            continue;
          }
        }
        
        yield [key, object[key]];
      }
    }
    

    Try it:

    console.config({ maximize: true });
    
    function* nonNumericProperties(object) {
      for (const key in object) {
        if (
          !Object.hasOwn(object, key) ||
          (/^(?:[1-9]d*|0)$/.test(key) && +key <= 2 ** 32 - 2)
        ) {
          continue;
        }
        
        yield [key, object[key]];
      }
    }
    
    const array = [0, 1, 2];
    array.property = 'property';
    array[Infinity] = Infinity;
    array[1.5] = 'float';
    array[2e-14] = 'float + scientific notation';
    array['00234'] = '0-padded';
    array[NaN] = NaN;
    array[2 ** 32] = 2 ** 32;
    
    for (const [key, value] of nonNumericProperties(array)) {
      console.log(key, value);
    }
    <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search