找到最接近的匹配JSON数组

时间:2018-02-07 18:11:22

标签: javascript arrays json dataset pattern-matching

我有一个JSON数据集,

{
 "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"]
}

我希望与测试数据最匹配,例如在下面,最接近的匹配是数据集中具有与测试数组相关的最低平均差异的数组。在这个例子中,最接近的匹配是“a”:[“73.0”,“41.0”,“98.0”,“43.0”],

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

任何可以帮助解决这个问题的图书馆?顺便说一下JS。

2 个答案:

答案 0 :(得分:1)

您可以迭代键和项目,并检查绝对差异,以获取结果数组的最接近值。



var 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);
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这个答案基于以下假设:

  • 您的json已解析且规范化,因此所有数组值均为数字
  • 您打算以绝对数量衡量差异diff(a, b) => Math.abs(a - b)
  • 您希望找到指向与最近匹配的数组的属性的

&#13;
&#13;
// We're gonna get the closest match from here
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],
};

// We're gonna find the closest match to this
const comparator = [75, 42, 100, 44];

// Gets the average value of all given numbers
const avg = (...numbers) => numbers.reduce((acc, n) => acc + n, 0) / numbers.length;

// Returns an array with the absolute numeric difference
// between corresponding indices within 2 given arrays of
// numbers.
const difference = (arr1, arr2) => arr1.map((num, i) => Math.abs(num - arr2[i]));

// Returns the key of source that contains the array that
// matches closest to predicate.
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: "${closestKey}": [${parsedJson[closestKey]}]`;
&#13;
&#13;
&#13;