Home > Net >  .find(predicate) returns array instead of boolean
.find(predicate) returns array instead of boolean

Time:12-06

I have an array containing many writing systems:

var SCRIPTS = [
  {
    name: "Adlam",
    ranges: [[125184, 125259], [125264, 125274], [125278, 125280]],
    direction: "rtl",
    year: 1987,
    living: true,
    link: "https://en.wikipedia.org/wiki/Fula_alphabets#Adlam_alphabet"
  },
  {
    name: "Han",
    ranges: [[11904, 11930], [11931, 12020], [12032, 12246], [12293, 12294], [12295, 12296], [12321, 12330], [12344, 12348], [13312, 19894], [19968, 40939], [63744, 64110], [64112, 64218], [131072, 173783], [173824, 177973], [177984, 178206], [178208, 183970], [183984, 191457], [194560, 195102]],
    direction: "ltr",
    year: -1100,
    living: true,
    link: "https://en.wikipedia.org/wiki/Chinese_characters"
  },
  // and many more entries
}

My task is to figure out to which writing system a character belongs:

scriptOfSample("英", SCRIPTS) // han

Here's my first appraoch, which is a working solution.

function scriptOfSample(a, scripts) {
    const codePoint = a.codePointAt(0)
    for (let language of scripts) {
        let isInRange = language.ranges.find(([from, to]) => from <= codePoint && codePoint <= to)
        if (isInRange) {
            return language.name
        }
    }

    return undefined
}

Out of curiosity I've tried to use an approach with the .forEach() method.

function scriptOfSample(a, scripts) {
    const codePoint = a.codePointAt(0)
    scripts.forEach(({ranges, name}) => {
        let isInRange = ranges.find(([from, to]) => from <= codePoint && codePoint <= to)
        if (Array.isArray(isInRange)) {
            console.log("found one")
            return name
        }
    })

    return undefined
}

However, in this case isInRange isn't a boolean value but contains the range [from, to] in which the predicate was true.

What I'd like to know:

  1. Why is the find() method returning different values?
  2. What can I do (How do I have to adjust my implementation), to check if value "is in range"?

CodePudding user response:

The comments are correct in saying that Array#find returns an element of the array or undefined. Since you're calling it on ranges which is an array of arrays, you get an array back.

You can use the Array#some method instead, which returns a boolean if the condition is met on any item of the array:

function scriptOfSample(a, scripts) {
    const codePoint = sample.codePointAt(0);

    if (codePoint == null) return undefined

    const system = scripts.find(
        (script) => script.ranges.some(
            ([from, to]) => from <= codePoint && codePoint <= to
        )
    );

    return system ? system.name : undefined
}
  • Related