简体   繁体   中英

javascript .some function for object property

I've got an array with multiple objects in it with the following information:

string ProductDescription/Name
int Amount

I want to create an new array that combines the Amount of the same productdescriptions. Example: the 1st array contains: Product X 50, Product X 80 and Product X 140.

My new array should be Product X 270. Now I found something about checking if a value is already in an array: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some

But I want something that will check the ProductDescription , instead of the object.

So I took the same function:

function checkAvailability(arr, val) 
{
    return arr.some(function(arrVal) 
    {
        return val === arrVal;
    });
}

And I try it like this:

var found = checkAvailability(arrayProduct['Productomschrijving'], javascript_array[i]['Productomschrijving']);

But it gives an error...

Uncaught TypeError: Cannot read property 'some' of undefined

When I do it like this:

var found = checkAvailability(arrayProduct, javascript_array[i]['Productomschrijving']);

It's always false. Kinda normal since it's comparing a string with objects.

So how can I get this solved that my some function is checking on the property of an object instead of the complete object?

Correct comparison should be val with arrVal.Productomschrijving :

function checkAvailability(arr, val) {
    return arr.some(function(arrVal) {
        return val === arrVal.Productomschrijving;
    });
}

do you have to use some() method

why not simply? check this fiddle

var objArray = [
   { name : "Product X", amount : 10 },
   { name : "Product X", amount : 100 },
   { name : "Product X", amount : 40 },
]

var newArray = [];
var keyValue = {};
for ( var counter = 0; counter < objArray.length; counter++ )
{
  var obj = objArray[ counter ];
  if ( !keyValue[ obj.name ] )
  {
    keyValue[ obj.name ] = 0;
  }
  keyValue[ obj.name ] += obj.amount;
}
for ( var key in keyValue )
{
  newArray.push( { name: key, amount : keyValue[ key ] } );
}

console.log( newArray );

The error message says only that arrayProduct['Productomschrijving'] is undefined . So maybe you have a typo or the property just does not exists.

As it's said and explained on your link :

Polyfill

some() was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of some() in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object and TypeError have their original values and that fun.call evaluates to the original value of Function.prototype.call().

You should create a prototype method of .some() for arrays.

// Production steps of ECMA-262, Edition 5, 15.4.4.17
// Reference: http://es5.github.io/#x15.4.4.17
if (!Array.prototype.some) {
  Array.prototype.some = function(fun/*, thisArg*/) {
    'use strict';

    if (this == null) {
      throw new TypeError('Array.prototype.some called on null or undefined');
    }

    if (typeof fun !== 'function') {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t && fun.call(thisArg, t[i], i, t)) {
        return true;
      }
    }

    return false;
  };
}

And when you define/prototype the .some() , you'll be able to use it on any array in your document/scope, ie:

function isBiggerThan10(element, index, array) {
  return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

Its a reduce , you can obtain the needed result with something like this:

var arr = [{p: 'X', v: 50}, {p:'Y', v: 12}, {p:'X', v:80}, {p:'X', v:140}]
arr.reduce(function(acc, curr){
  if (acc[curr.p]){
    acc[curr.p] = acc[curr.p] + curr.v
  } else {
    acc[curr.p] = curr.v
  }
    return acc;
  }, {});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM