A collection of closest values from two arrays

Related searches

I'm looking for optimization of an algorithm to solve a simple problem which may be hard to explain. I'm not looking for a speed or performance but simplicity and clarity when you read the code. Maybe someone has more clever solution than mine. I imagine one-liner would probably be an overkill.

I have two collections of cells ordered by date. Each of the cell can have a price value. We can assume that there can't be a price in two cells for the same date. I want to have one collection of dates, but where is no price for the date:

  • which collection have a closest price from the past
  • if there is no price in the past, look in the future

Here's what I have so far (it gives accurate results):

const array1 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12' },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15', price: 10 },
  { date: '2019-11-16' },
];

const array2 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12', price: 10 },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15' },
  { date: '2019-11-16' },
];

const merged = Object.values(array1).map((element, index) => {
  let filled;
  if (element.price) {
    filled = 1;
  }
  if (array2[index].price) {
    filled = 2;
  }
  if (filled) {
    return {
      date: element.date,
      filled
    }
  } else {
    return {
      date: element.date
    }
  }
});

const first = merged.find(element => element.filled);

let currentFill = first && first.filled;

const emptyMap = merged.map((element, index, array) => {
  if (!element.filled) {
    return {
      date: element.date,
      empty: currentFill
    }
  }
  currentFill = element.filled;
  return element;
})

console.log(emptyMap);

const array1 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12' },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15', price: 10 },
  { date: '2019-11-16' },
];

const array2 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12', price: 10 },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15' },
  { date: '2019-11-16' },
];

function collect(collection1, collection2) {
  let firstEmptyId = null
  let currentId = null
  let indexes = [/* [1] optimization */]
  let collection = collection1.map(({ date, price }, i) => (
    ((price && (currentId = 1)) || (collection2[i].price && (currentId = 2)))
      ? ((firstEmptyId || (firstEmptyId = currentId)), { date, filled: currentId })
      : ((firstEmptyId || /*see[1]*/ indexes.push(i)), { date, empty: currentId })
  ))
  // only two iterations => index.length === 2
  indexes.forEach((i) => (collection[i].empty = firstEmptyId))
  return collection
}

console.log(collect(array1, array2))

How to find closest elements in two array?, I want to define a function to find the the corresponding index in the two arrays, like in first case: y[0] correspond to X[0] ,; y[1] correspond to X[1]� Given two sorted arrays and a number x, find the pair whose sum is closest to x and the pair has an element from each array. We are given two arrays ar1[0…m-1] and ar2[0..n-1] and a number x, we need to find the pair ar1[i] + ar2[j] such that absolute value of (ar1[i] + ar2[j] – x) is minimum.

Here's my spin on this:

const array1 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12' },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15', price: 10 },
  { date: '2019-11-16' },
];

const array2 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12', price: 10 },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15' },
  { date: '2019-11-16' },
];

const mappedToCollection = array1.map((el, i) => ({
  date: el.date,
  //You can just as easily store the actual collection here and not just a number
  collection: (el.price && 1) ||
    (array2[i].price && 2) ||
    undefined,
}));

const firstExactMatch = mappedToCollection.find(el => el.collection);

const closestCollections = mappedToCollection.reduce((acc, el, i) => [
  ...acc,
  {
    date: el.date,
    collection: el.collection ||
      (acc[i-1] && acc[i-1].collection) ||
      (firstExactMatch && firstExactMatch.collection),
    exactMatch: !!el.collection,
  },
], []);

console.log(closestCollections);

finding closest values in two arrays without repetitions, Probably not the best way to do it, but you could keep a copy of that list2 array and modify it every time you find a match. Something like this: Hello . Im am trying to get my data from a collection into a vertical gallery (insert>gallery>vertical) the problem is that the data i get from my request starts with an array "result[]" so i cant just use my collection as datasource in a vertical gallery. How do i cut every company value out of this

To my understanding, what will probably make the code most difficult to read is the last statement: "if there is no price in the past, look in the future".

This requirement means that instead of going forward only through the collections and only applying values from previously handled elements where necessary, you have to also look ahead until something happens.

For greatest simplicity, I recommend to go once from front to back, ignoring the "look ahead" part, and then, in the resulting collection, go once from back to front copying the last reached (i. e. earliest) filled element to the ones in front:

const array1 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12' },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15', price: 10 },
  { date: '2019-11-16' },
]

const array2 = [
  { date: '2019-11-10' },
  { date: '2019-11-11' },
  { date: '2019-11-12', price: 10 },
  { date: '2019-11-13' },
  { date: '2019-11-14' },
  { date: '2019-11-15' },
  { date: '2019-11-16' },
]

const length = array1.length
const result = new Array(length)
let emptySource = undefined

// First run: from earlier to more recent
// Applies value for "empty" when price was available once
for (let i = 0; i < length; ++i) {
  let e1 = array1[i]
  let e2 = array2[i]
  const date = e1.date
  if (e1.price) {
    result[i] = {
      'date': date,
      'filled': 1
    }
    emptySource = 1
  } else if (e2.price) {
    result[i] = {
      'date': date,
      'filled': 2
    }
    emptySource = 2
  } else {
    result[i] = {
      'date': date,
      'empty': emptySource
    }
  }
}

// Second run: from more recent to earlier
// Finds the earliest element ever "filled",
// then applies its value to all still unset "empty" elements
// (which necessarily all have a lower index)
for (let i = length - 1; i >= 0; --i) {
  const e = result[i]
  if (e.filled) {
    emptySource = e.filled
  } else if (e.empty === undefined) {
    e.empty = emptySource
  }
}

console.log(result)

Find closest value in array - MATLAB Answers, Note that if there is a tie for the minimum value in each column, MATLAB chooses the first element in the column. 3 Comments. In the following solutions, it is assumed that all elements of array are distinct. A simple solution is to do linear search for k closest elements. 1) Start from the first element and search for the crossover point (The point before which elements are smaller than or equal to X and after which elements are greater).

NumPy: Find the closest value (to a given scalar) in an array , It seems that if the value you're comparing with has an equal "distance" between two values in the list it rounds it down to the smaller of the two. Given a sorted array and a number x, find the pair in array whose sum is closest to x; Closest pair in an Array such that one number is multiple of the other; Find k closest elements to a given value; Find three closest elements from given three sorted arrays; Find the closest pair from two sorted arrays; Closest product pair in an array

Program to find the nearest value pair among the two sorted arrays, Challenging Task: Among the given two arrays (a1 and a2) with m and n elements, find a pair of elements a1[x1], a2[x2] such that (a1[x1] +� Two elements whose sum is closest to zero; Find k closest elements to a given value; Find the Sub-array with sum closest to 0; Find closest value for every element in array; Closest product pair in an array; Find closest number in array; Minimum number closest to N made up of odd digits only; Closest pair in an Array such that one number is

Find closest value in array. Learn more about vector, array, closest value . If two are the same, like in this example with two different '2001's, it will return

Comments
  • Wouldn't it be better to have date and price in the output? If you want to know prices for a date you still have to find it. Optionally you could add a property that tells you from which collection the price comes and/or one that tells you if it is a price of the past, future or exactly for that date. Maybe even better: make an object with the dates as keys, so you can query prices for those dates in O(1).
  • I'm open to any suggestions even if it means to change the structure. The most important is that I have two separate collections of dates that some of them have prices and I need to merge it with those 2 conditions in mind.
  • This is the great answer.
  • Sometimes, I'm still wondering how code containing (({,},)=>(((&&(=))||([].&&(=)))?((||(=)),{,:}):((||.()),{,:}))) can be the answer if "simplicity and clarity when you read the code" was the question.
  • Very nice approach. I definitely like it more than mine. Thanks!
  • Well yes, it definitely works and is very clear and blunt. On the other hand the code is now long and for example going twice through the array and putting date in all 3 conditions is not necessary if we know for sure it's gonna be there anyway. I'm looking for some balanced solution between primitive yet clear and codegolf/one-liner clever yet unreadable code. Thanks for the input though.
  • The "3 conditions" are an artifact of your (implied) requirement to differentiate between "filled" and "empty" property. I wrote the code so it produces the exact output yours did. If this is not required, I can shorten the code massively.
  • I'd like very much to see the shorter version :)