Determine the most similar JSON array

My dataset is in JSON format,

{
 "a": ["73.0", "41.0", "98.0", "43.0"],
 "s": ["74.0", "43.0", "112.0", "44.0"],
 "f": ["75.0", "45.0", "116.0", "45.0"],
 "l": ["76.0", "47.0", "120.0", "46.0"],
 "x": ["77.0", "49.0", "128.0", "47.0"],
 "q": ["78.0", "51.0", "134.0", "48.0"]
}

I need to find the closest match to a test data set like the one below. The closest match is determined by the array in the dataset with the lowest average difference compared to the test array. For example, in this case, the closest match is "a": ["73.0", "41.0", "98.0", "43.0"].

{
 "t": ["75.0", "42.0", "100.0", "44.0"]
}

Are there any JavaScript libraries that can assist with this task?

Answer №1

This solution assumes the following conditions:

  • Assumption that the JSON data is already parsed and normalized, with all array values as numbers
  • The objective is to measure the difference in absolute numbers using the formula: diff(a, b) => Math.abs(a - b)
  • The goal is to identify the key of the property pointing to the array that closely matches the comparator array

// Seeking the closest matching array from the given data
const parsedJson = {
    a: [73, 41, 98, 43],
    s: [74, 43, 112, 44],
    f: [75, 45, 116, 45],
    l: [76, 47, 120, 46],
    x: [77, 49, 128, 47],
    q: [78, 51, 134, 48],
};

// The array for which we want to find the closest match
const comparator = [75, 42, 100, 44];

// Calculate the average value of a set of numbers
const avg = (...numbers) => numbers.reduce((acc, n) => acc + n, 0) / numbers.length;

// Function to get the absolute numeric difference between two arrays
const difference = (arr1, arr2) => arr1.map((num, i) => Math.abs(num - arr2[i]));

// Find the key in the source object containing the array that best matches the comparator
const closestMatch = (comparator, source) => {

    const [keyOfClosestMatch] = Object
        .keys(source)
        .map(key => [key, avg(...difference(comparator, source[key]))] )
        .reduce((lowestSoFar, nextPredicate) => {
        return lowestSoFar[1] < nextPredicate[1]
            ? lowestSoFar
            : nextPredicate;
    });

    return keyOfClosestMatch;
}

let closestKey = closestMatch(comparator, parsedJson);
document.body.innerText = `Closest Match: "${closestKey}": [${parsedJson[closestKey]}]`;

Answer №2

One way to approach this problem is by iterating through the keys and items, calculating the absolute difference in order to find the closest values for the result array.

let data = { a: ["73.0", "41.0", "98.0", "43.0"], s: ["74.0", "43.0", "112.0", "44.0"], f: ["75.0", "45.0", "116.0", "45.0"], l: ["76.0", "47.0", "120.0", "46.0"], x: ["77.0", "49.0", "128.0", "47.0"], q: ["78.0", "51.0", "134.0", "48.0"] },
    test = ["75.0", "42.0", "100.0", "44.0"],
    result = Object.keys(data).reduce(function (r, k, j) {
        data[k].forEach(function (a, i) {
            if (!j || Math.abs(a - test[i]) < Math.abs(r[i] - test[i])) {
                r[i] = a;
            }
        });
        return r;
    }, []);

console.log(result);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporating YouTube links into calendar events for each specific date

Our team is currently developing an online class website where our client wants to incorporate recorded classes. These recorded classes will be uploaded to YouTube in unlisted format and then linked to specific calendar dates. I will share the code for the ...

Issue with updating data variable from watcher on computed property in Vue.js with Vuex

Snippet: https://jsfiddle.net/mjvu6bn7/ I have a watcher implemented on a computed property in my Vue component. This computed property depends on a Vuex store variable that is set asynchronously. Despite trying to update the data variable of the Vue comp ...

What is the best way to categorize elements in an array of objects with varying sizes based on two distinct properties in JavaScript?

I am faced with a scenario where I have two distinct arrays of objects obtained from an aggregate function due to using two different collections. Although I attempted to utilize the map function as outlined here, it proved unsuccessful in resolving my is ...

Beware: The use of anonymous arrow functions in Next.js can disrupt Fast Refresh and lead to the loss of local component state

I am currently encountering a warning that is indicating an anonymous object in a configuration file, and even specifying a name for it does not resolve the warning. Below you will find the detailed warning message along with examples. Warning: Anonymous ...

Is it necessary to bump the major version if I make updates to a react module that does not affect existing code functionality, but may cause Jest snapshot tests to break?

Imagine I am developing a module for a react component and currently working on a PR to introduce a new feature. Along with this new feature, I have also made changes to the component by refactoring it to eliminate certain internal parts that were previou ...

Calculating the size of an array by using the sizeof operator along with an offset

I was pondering about sizeof(arrayName + offset). It returns the sizeof(pointer). Even though the array name is essentially a constant pointer in C, sizeof(arrayName) provides the size in bytes of an array. Therefore, it seems like the compiler interprets ...

How can I create 3 conditions in an AJAX request to verify a user's ID?

I am trying to create 3 conditions in Ajax to check when creating a new user id. It works for 2 conditions (username can be used and username is already in use), but I encounter a problem when the user leaves the username field empty, and it still displays ...

Using Python to handle JSON data in POST requests and responses within a Django application

Trying to send a post request to a Django API using the requests package in Python. Request: data = {"key1":"123", "key2":[{"a":"b"},{"c":"d"}]} response = requests.post("http://127.0.0.1:8000/api/postapi/", data=data) On the server side, the parameter ...

A more efficient method for transforming HTML/CSS into images

I'm in the process of developing a web application that allows users to easily create advertising banners. With this tool, users can add various elements onto a banner such as text, images, and boxes by simply dragging and dropping them onto the canva ...

What is the process for inputting data into a Inertia component?

I have a simple component: <script setup> import {ref} from 'vue' const labels = [] </script> <template> <div v-for="(label, index) in labels" :key="index" v-html="label"></div> </t ...

Leveraging various routes to access data with a shared VueJS 3 component

Could you please review this code snippet: It displays two routes that utilize the same component to fetch content from an API. Main.js const router = createRouter({ history: createWebHistory(), routes: [ { path: "/route1& ...

Using Cucumber for testing javascript-loaded content can be incredibly powerful and effective in ensuring the functionality

As I develop my Rails application, I've decided to incorporate a combination of Test Driven Development and Behavioral Driven Development into my process. The challenge arises as my app utilizes the MochaUI web application user interface framework, w ...

Add an item to an array that contains objects within an array of other objects

How can I properly push the values "label" and "link" into an object within "data" based on the id match with the "parent" value of another object? The goal is to insert these values into the "children" property of the corresponding target object, but it d ...

Trim the final digits from the arrays

I have an array that contains various strings: var arr = ['1234','23C','456','356778', '56'] My goal is to filter out array elements that are less than 3 characters or more than 4 characters. The resultin ...

Exploring the concept of Promises through the lens of recursion

I am dealing with a MongoDB collection that looks like this [ { "classId": "1", "name": "Input", "definition": [ { "property": [ { "classId": "12", "name": "One" }, { ...

Angular Bootstrap multi-typeahead component glitches

Currently, I am utilizing the bootstrap angular typehead feature. When using it for a single input field, everything functions as expected. However, upon attempting to implement multiple instances, I encounter an issue where one dropdown interferes with th ...

Error: Attempting to access properties of an undefined variable (specifically 'document') is not allowed

The other day, while working on a project, I encountered an issue with my GraphQL implementation using the JavaScript graphql-request library. Here is the snippet of code that caused the error: import { request, gql } from 'graphql-request' const ...

Destructuring and For of Loop in ES6: Capturing the first object only

Working with my react app, I have a specific object called 'topics' that I am looping through: const topics = [ {name: 'Mon', color: 'blue', id: 1}, {name: 'Tue', color: 'red', id: 2}, {name: 'W ...

I wonder about the origin of this variable

I found this example in a textbook. My confusion lies in the origin of this interval variable. Where does it come from? It's not defined within the data block, and you can't simply create a variable by assigning a value to it. Could it possibl ...

How to style a div for printing using CSS

Currently, I am working on a project that has already been completed but now requires some enhancements. To give you an overview, the project includes a search functionality that displays additional details upon clicking on the displayed name in the result ...