Failed to check the full length of nested children

I have 1 object that contains a nested child, as shown below:

$scope.artists.materials.items[] 

Now I will have several artists who will contain a list of elements, but in this I want to check the total length of each element of artists and if a discrepancy is found, then I want to return true or false.

The problem is that I do not have elements for any artist, I get false

The idea here is to keep the length of the elements from the first artist and make sure that they all have the same length of elements.

The code:

function checkItemsValidity() {
      for (var i = 1; i < $scope.artists.length; index++) {
            if ($scope.artists[i].materials.items != undefined && $scope.artists[0].materials.items) {
                if($scope.artists[i].materials.items.length != $scope.artists[0].materials.items[0].length) {
                             return false;
                }
            }        
                             return false;
        }
            return true;
    }

Case 1 . In the case of only one artist, then return true, because no other artist compares

2. 2- true else false;

3. 3- 2 artist1 2 5 artist3, false;

- ?

+4
7

...

function checkMaterials (arists)
{
  if (!artists || !artists.length) { return false; }
  if (artists.length < 2)          { return true; }

  var valid = true;
  var materialCount

  try
  {
    //All artists must have the same number of materials, so we
    //can test against the number of materials that the first
    //artist has and reduce the number times we access the object
    materialCount = (artists[0].materials.items || []).length;
  }
  catch (exception)
  {
    //Object is malformed
    return false;
  }

  //Loop through the remaining artists and check how
  //many materials they have against the first artist
  for (var i = 1; i < artists.length; i++)
  {
    if (!artists[i].materials || ((artists[i].materials.items || []).length !== materialCount)
    {
      //Once one failed case is found, we can stop checking
      valid = false;
      break;
    }
  }

  return valid;
}

//Test data
var validArtists = [{
  materials: {
    items: [1, 2, 3]
  }
}, {
  materials: {
    items: [1, 3, 4]
  }
}];

var invalidArtists = [{
  materials: {
    items: [1, 2]
  }
}, {
  materials: {
    items: [3]
  }
}];

//Tests
console.log (checkMaterials (validArsists)); //Prints true
console.log (checkMaterials (invalidArtists)); //Prints false
+1

, , . :

var result, materialsNumber;
for (var artist of $scope.artists) {
   var artistMaterialsNumber = artist.materials.items.length;
   if (!materialsNumber) {
       materialsNumber = artistMaterialsNumber;
   }
   result = (materialsNumber === artistMaterialsNumber);
   if (!result) {
      break;
   }
}

return result;

. , . false.

+4

Hi, you can also try this ...

var vFirstItemLength = artists[0].materials.items.length;
result = (artists.filter(function(item){return item.materials.items.length===vFirstItemLength;}).length === (artists.length));
+2
source

var artists = [{
	materials: {
		items: [1, 2, 3]
	}
}, {
	materials: {
		items: [1, 3]
	}
}, {
	materials: {
		items: [1, 2, 3]
	}
}, {
	materials: {}
}];

artists.some(function(artist, i) {
	if (i === 0) return false;
	if (artists.length === 1) {
		console.log("Index " + i);
		console.log(true);
		return true; // length is one
	}
	if (artists[0].materials.items) {
		if (!artist.materials.items) {
			console.log("Index " + i);
			console.log(false);
			return false; // items doesn't exist. Return true/false, whatever works for you
		} else if (artist.materials.items &&
			artist.materials.items.length === artists[0].materials.items.length) {
			console.log("Index " + i);
			console.log(true);
			return true; // length is equal
		} else {
			console.log("Index " + i);
			console.log(false);
			return false; // length is unequal
		}
	} else {
		if (artist.materials.items) {
			console.log("Index " + i);
			console.log(false);
			return false; // one has  items, other doesn't
		} else {
			console.log("Index " + i);
			console.log(true);
			return true; // both have no items
		}

	}
});
Run codeHide result

Why don't you try

artists.some(function(artist, i) {
    if (i === 0) return false;
    if (artists.length === 1) {
        console.log("Index " + i);
        console.log(true);
        return true; // length is one
    }
    if (artists[0].materials.items) {
        if (!artist.materials.items) {
            console.log("Index " + i);
            console.log(false);
            return false; // items doesn't exist. Return true/false, whatever works for you
        } else if (artist.materials.items &&
            artist.materials.items.length === artists[0].materials.items.length) {
            console.log("Index " + i);
            console.log(true);
            return true; // length is equal
        } else {
            console.log("Index " + i);
            console.log(false);
            return false; // length is unequal
        }
    } else {
        if (artist.materials.items) {
            console.log("Index " + i);
            console.log(false);
            return false; // one has  items, other doesn't
        } else {
            console.log("Index " + i);
            console.log(true);
            return true; // both have no items
        }

    }
});
+1
source

It is necessary to solve the problem:

function checkValidity() {
    var itemsCounts = $scope.artists.map(function(artist) { return artist.materials.items.length; });
    return itemsCounts.length > 1
        ? itemsCounts.every(function(count) { return count === itemsCounts[0]; })
        : true;
}
+1
source

Perhaps you can do the following:

var artists = [{ materials: { items: [1, 2, 3] } },
               { materials: { items: [1, 2] } },
               { materials: { items: [] } },
               { materials: { items: [1] } },
               { materials: { items: [1, 2, 3] } }
              ];
     result = artists.map(artist => artist.materials.items.length)
                     .every(length => length === artists[0].materials.items.length);
console.log(result);
Run codeHide result

var artists = [{ materials: { items: [1, 2, 3] } }
              ];
     result = artists.map(artist => artist.materials.items.length)
                     .every(length => length === artists[0].materials.items.length);
console.log(result);
Run codeHide result
+1
source

Decision:

function checkItemsValidity() {
  if ($scope.artists.length === 1) {
      return true;
  }

  for (var i = 0; i < $scope.artists.length; i++) {
    //this condition might be unnecessary, I assumed items can be undefined from your code.
    if (typeof $scope.artists[i].materials.items === 'undefined') {
        $scope.artists[i].materials.items = [];
    }
    if (i === 0) {
        continue;
    }
    if ($scope.artists[i].materials.items.length !== $scope.artists[0].materials.items.length) {
        return false;
    }
  }

  return true;
}

And a fiddle with some tests: https://jsfiddle.net/6x7zpkxe/1/

+1
source

Source: https://habr.com/ru/post/1656345/


All Articles