How to return undefined instead of -1, findLastIndex() - arrays

In this challenge, I need to return the index position of the last element that is true for a callback. I know findLastIndex returns the last index position, however I need to return 'undefined' instead of -1 if the callback doesn't result in true. findLast() does this, so this was the only solution I could come up with. I believe there has to be a better way, my way feels silly. I have two arrays for testing.
function findLastTrueElement(array, callback) {
for(let i = 0; i < array.length; i++) {
let cb = callback(array[i])
if (cb === true) return array.findLastIndex(callback)
}
return array.findLast(callback)
}
const nums = [11, 12, 13, 14, 15, 16, 17, 18, 19];
//all odd array
// const nums = [11, 17, 13, 19, 15, 9, 17, 7, 19];
function isEven(n) {
return (n % 2 === 0)
}
console.log(findLastTrueElement(nums, isEven))

Related

How to Search and Replace object property value if each key has an array of numbers? Javascript

Let's say we have an object with an array of numbers for each property:
const obj = {
line1: [2, 13, 7, 6, 14],
line2: [25, 16, 24, 27, 28],
line3: [41, 31, 32, 44, 42],
};
How can we Search for a specific number and Replace it with another number?
Let's say we would like to find number 44 and replace it with 88? In a modern JS way...
You can use loop to iterate on each key-value pair of the object, and then you can find and replace the number you want in the array. Keep in mind that if the number can be more than once in the same array you will have to loop on the array as well, otherwise you can use indexOf and assign the new value.
Here is an example:
const obj = {
line1: [2, 13, 7, 6, 14],
line2: [25, 16, 24, 27, 28],
line3: [41, 31, 32, 44, 42],
};
const changeNumber = (oldNum, newNum, obj) => {
for (const [key, arr] of Object.entries(obj)) {
const index = arr.indexOf(oldNum);
if (index > -1) {
arr[index] = newNum;
}
}
}
console.log(obj); // Before
changeNumber(44, 88, obj);
console.log(obj); // After
/* With duplicates entries */
const changeNumberDuplicate = (oldNum, newNum, obj) => {
for (const [key, arr] of Object.entries(obj)) {
let index = 0;
do {
index = arr.indexOf(oldNum, index);
if (index > -1) {
arr[index] = newNum;
}
} while (index > -1);
}
}
const objDup = {
line1: [2, 13, 44, 6, 44],
line2: [44, 16, 44, 27, 28],
line3: [41, 44, 32, 44, 42],
};
console.log(objDup); // Before
changeNumberDuplicate(44, 88, objDup);
console.log(objDup); // After

angular 8 array change in console but not in view

Hello community i'm new to angular and i'm trying to make a pagination component with logic, at this point i'm successfully getting the correct array in the console but in the view it is not changing.
i'm able to move through pages correctly only the pagination component itself is not changing.
pagination view
the console i get when i navigate through the pages:
pagination.component.ts:25 (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pagination.component.ts:25 (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pagination.component.ts:25 (10) [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
pagination.component.ts:25 (10) [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
pagination.component.ts:25 (10) [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
this is the function in the service that create the array that show correctly on console but not in the view.
initialPagination(totalPages: number) {
this.pagination = [];
this.numberOfPages = totalPages
if (this.numberOfPages <= 10) {
// less than 10 total pages so show all
this.startPage = 1;
this.endPage = this.numberOfPages;
} else {
// more than 10 total pages so calculate start and end pages
if (this.pageToShow <= 6) {
this.startPage = 1;
this.endPage = 10;
} else if (this.pageToShow + 4 >= this.numberOfPages) {
this.startPage = this.numberOfPages - 9;
this.endPage = this.numberOfPages;
} else {
this.startPage = this.pageToShow - 5;
this.endPage = this.pageToShow + 4;
}
}
// create an array of pages to ng-repeat in the pager control
for (let i = this.startPage; i < this.endPage + 1; i++) {
this.pagination.push(i)
}
return this.pagination
}
over here is the component itself
<ul class="pagination">
<li (click)="replacePage(pagination.pageToShow - 1)"><a>«</a></li>
<li (click)="replacePage(i)" [ngClass]="{active:pagination.pageToShow === i}"
*ngFor="let page of pager; let i = index"><a>{{i + 1}}</a></li>
<li (click)="replacePage(pagination.pageToShow + 1)"><a>»</a></li>
and here is the initialization of the pagination:
replacePage(page: number) {
if (page >= 0) {
if (page < this.numberOfPages) {
this.pagination.pageToShow = page;
this.pager = this.pagination.initialPagination(this.numberOfPages)
console.log(this.pager)
}
}
}
why iis the view not update but console is?
The view loops through the elements of pager, and displays the index of each element. And whenever you click, you change the elements of pager, but pager is still an array of 10 elements, with indices thus still going from 0 to 9.
You need to display the elements of the array, rather than its indices.

Google apps script: array as property of an object is the same in all instances of the object

I have a simple object with two properties, one string and one array. When I create a few variables, each as a new instance of my object using Object.create, all my variables have their own string properties, but they all share the same array! If you run the code below step by step, you can see at each affectation of the array that all the arrays of the previous variable are also edited !!! (but the string property is ok). Indeed, we can see that the arrays in all the variables are in fact the same array thanks to the ObjectId of the debugger... Do you know how to make each array specific to each variable and not having all the variables sharing the same object?
function myFunction() {
// Object definition
var my_object = Object.create(null, {
my_object_name: {value: new String(), enumerable: true, writable: true},
my_object_array: {value: new Array(), enumerable: true, writable: true},
build: {
value: function (i) {
this.my_object_name = "name_" + i.toString();
for (var j = 0; j <= 4; j++) {
this.my_object_array[j] = i + j;
}
return this;
}
}
});
// Main
var my_variable_1 = Object.create(my_object).build(1);
var my_variable_2 = Object.create(my_object).build(5);
var my_variable_3 = Object.create(my_object).build(10);
}
At then end, we will obtain the result below, with all different strings for my_object_name property but all the same arrays for the my_object_array property
my_variable_1.name = "name_1" / my_variable_1.array = [10, 11, 12, 13, 14]
my_variable_2.name = "name_2" / my_variable_1.array = [10, 11, 12, 13, 14]
my_variable_3.name = "name_3" / my_variable_1.array = [10, 11, 12, 13, 14]
But I would like to find:
my_variable_1.name = "name_1" / my_variable_1.array = [ 1, 2, 3, 4, 5]
my_variable_2.name = "name_2" / my_variable_1.array = [ 5, 6, 7, 8, 9]
my_variable_3.name = "name_3" / my_variable_1.array = [10, 11, 12, 13, 14]
Your my_object_array sits on the prototype and every access leads to same array through prototype chain. Different properties have to sit on the objects themselves.
Try this -
// constructor
function MyObject(i) {
this.name = 'name_' + i; // own
this.array = this.build(i); // own
}
// on prototype = shared
MyObject.prototype.build = function(i) {
var arr = [];
for (var j = 0; j <= 4; j++) {
arr[j] = i + j;
}
return arr;
};
// Main
var my_variable_1 = new MyObject(1);
var my_variable_2 = new MyObject(5);
var my_variable_3 = new MyObject(10);
console.log(my_variable_1.array);
console.log(my_variable_2.array);
console.log(my_variable_3.array);
// [ 1, 2, 3, 4, 5 ]
// [ 5, 6, 7, 8, 9 ]
// [ 10, 11, 12, 13, 14 ]

Delete as many elements from the beginning of an array that match a value, until array reaches a specified size

I'm trying to modify an array by deleting values that match a unique ID, but then stop once the first 5 values of the array are valid (i.e. their IDs do not match the undesired ones). If the array has a count <= 5, then this suffices:
all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"}]
exclude_ids = ["id01","id02"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}
and the desired output is [{"id" => "id03"},{"id" => "id04"}].
But in the case where the total count of the array is >= 5, I want to delete only as many of the first items as necessary until the first 5 elements (all_items[0..4]) are all valid within the set criterion, and then stop iterating. If I were to do this:
all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
exclude_ids = ["id01","id02","id07"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}
return all_items[0..4]
I do get the desired output, [{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id08"}]. But I want the delete_if to completely stop once it reaches the point where all_items[0..4] already contains 5 valid elements. In this instance, I would want it to break after {"id" => "id08"}, and not even check the remaining values. (If, however, while the delete_if is running, the total count dips below 5, then it should continue iterating over all remaining elements, as it would fall into the category of the first piece of code I posted above, where the count <= 5.)
I know there is a delete_if.with_index, but I'm not sure if it's appropriate in this context, especially since the index would be shifting as items are deleted.
To summarize my question: is there a way to delete as many first items from an array as is required until array[0..x] is populated by desired values, and then stop checking/deleting any remaining items once that count of x is reached?
termination_threshold = 5
all_items = (1..20).to_a
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
exclusions = [1,2,7]
all_items.reject! do |n|
break if termination_threshold.zero?
exclude = exclusions.include? n
termination_threshold -= 1 if exclude
exclude
end
#=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
all_items
#=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
The following could be used if only an array containing the first termination_threshold valid elements of all_items were desired:
all_items.each_with_object([]) do |e,arr|
arr << e unless exclusions.include?(e)
break arr if arr.size == termination_threshold
end
#=> [3, 4, 5, 6, 8]
If you delete from the original object you end up with all the items that had not been deleted. So, I gues it is better to move just the desired items to a new object:
all_items.each_with_object([]) { |item, ary| ary << item if !exclude_ids.include?(item["id"]) and ary.size < 5 }
#=> [{"id"=>"id03"}, {"id"=>"id04"}, {"id"=>"id05"}, {"id"=>"id06"}, {"id"=>"id08"}]
You can use Enumerator::Lazy to achieve what you want:
all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
exclude_ids = ["id01","id02","id07"]
all_items.lazy.reject {|item| exclude_ids.include?(item['id']) }.first(5)

How to find the lowest number in an array? [duplicate]

This question already has answers here:
Find min / max value in Swift Array
(16 answers)
Closed 1 year ago.
I am writing an algorithm to find the lowest number in an array however my print statement keeps saying that the lowest number is 0. I have the following:
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
func findMin(numbers: NSArray) {
var minValue = numbers[0]
var isSmallest: Bool
for i in 0...numbers.count {
isSmallest = true
for j in 0...numbers.count {
if i > j {
isSmallest = false
}
}
if isSmallest {
minValue = i
}
}
print("Smallest value in the list is \(minValue)")
}
findMin(numbers: list as NSArray)
My print statement returns as:
"Smallest value in the list is 0\n"
I feel like the algorithm is correct. Any ideas?
EDIT: Answered my own question
I was iterating over indices and not actual values. Thanks to one of the users in the comments. The correct code should be:
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
func findMin(numbers: NSArray) {
var minValue = numbers[0]
var isSmallest: Bool
for i in list {
isSmallest = true
for j in list {
if i > j {
isSmallest = false
}
}
if isSmallest {
minValue = i
}
}
print("Smallest value in the list is \(minValue)")
}
findMin(numbers: list as NSArray)
Simply
let list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
let minValue = list.min()
For logic use try this
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
var minValue = list[0]
for num in list {
minValue = (num < minValue) ? num : minValue
}
print("Smallest value in the list is \(minValue)")
For direct get min value by property
let list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
let minValue = list.min()
Or you could just use
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
list.min() // returns 2
If you'd like to find the min value without an extra loop, try this:
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
func findMin(numbers: NSArray) {
var minValIdx = 0
var minValue = numbers[0] as! Int
for i in 1..<numbers.count {
if (numbers[i] as! Int) < minValue {
minValue = numbers[i] as! Int
minValIdx = i
}
}
print("Smallest value in the list is \(minValue)")
}
findMin(numbers: list as NSArray)
You can use this code in Swift for manual algorithm:
let list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
var smallest = list[0]
for item in list {
if (item < smallest) {
smallest = item
}
}
print("smallest number is: \(smallest)")
And if you want Swift to do the hard work then use this:
let smallest = list.min()
print("smallest number is: \(smallest)")
here it is your solution
let numbers = [1, 6, 3, 9, 4, 6]
let min = minElement(numbers) // 1
let position = find(array, min)// it will return index
Just to throw a few more options out there, assuming you have to actually show some logic:
func min<T:Comparable>(_ elements:[T]) -> T? {
guard let first = elements[0] else {
return nil
}
return elements.reduce(first, min)
}
print(min(list))
or put it in an extension, this is essentially the definition of Array.min
extension Array where Element : Comparable {
func smallest() -> Element? {
guard let first = self.first else {
return nil
}
// Use 'Swift.min' to get to the global function since Array
// already has a min function
return reduce(first, Swift.min)
}
}
print(list.smallest())
You can use this code:
it is in C#
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
int minVal = list[0];
for (int i = 1; i < list.Length; i++)
{
if (list[i] < minVal)
{
minVal = intArray[i];
}
}
To find the minimum element in the sequence, Swift 3 have an istance method called min():
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
let minElem = list.min()
If the sequence has no elements, returns nil.
This method can be used also for a list of floats:
let heights = [67.5, 65.7, 64.3, 61.1, 58.5, 60.3, 64.9]
let minHeight = heights.min()
You can find the official document referece here

Resources