【问题标题】:Lodash : return first key of object whose value(i.e Array) has a given element (i.e string) in itLodash:返回其值(即数组)具有给定元素(即字符串)的对象的第一个键
【发布时间】:2016-04-30 19:17:47
【问题描述】:

我有一个类似的对象:

var obj = {
  "01": ["a","b"],
  "03": ["c","d"],
  "04": ["e","c"]
};

我知道对象键值的数组元素(比如“c”)然后如何使用 lodash 找到第一个键值,即“03”而不使用 if else?

我用 lodash 和 if else 试过这样:

var rId = "";
_.forOwn(obj, function (array, id) {
     if (_.indexOf(array, "c") >= 0) {
           rId = id;
           return false;
     }
});

console.log(rId); // "03"

预期结果:如果元素与“”匹配,则第一个键即“03”。

看过cmets之后:现在我也很想知道

我是否需要使用原生 javascript(如果我们使用超过 2 个 if 块的情况下难以阅读程序)或 lodash 方式(一行中易于阅读的程序解决方案)?

【问题讨论】:

标签: javascript lodash


【解决方案1】:

由于您只是想要一种能够使用简单的 Lodash 命令找到密钥的方法,因此以下应该可以工作:

_.findKey(obj, function(item) { return item.indexOf("c") !== -1; });

或者,使用 ES6 语法,

_.findKey(obj, (item) => (item.indexOf("c") !== -1));

这将为您的示例返回“03”。

谓词函数 - findKey() 的第二个参数 - 可以自动访问键的值。如果没有找到与谓词函数匹配的内容,则返回undefined

findKey() 的文档是 here


来自文档的示例:

var users = {
  'barney':  { 'age': 36, 'active': true },
  'fred':    { 'age': 40, 'active': false },
  'pebbles': { 'age': 1,  'active': true }
};

_.findKey(users, function(o) { return o.age < 40; });
// → 'barney' (iteration order is not guaranteed)

// The `_.matches` iteratee shorthand.
_.findKey(users, { 'age': 1, 'active': true });
// → 'pebbles'

// The `_.matchesProperty` iteratee shorthand.
_.findKey(users, ['active', false]);
// → 'fred'

// The `_.property` iteratee shorthand.
_.findKey(users, 'active');
// → 'barney'

【讨论】:

  • 我正在做 node.js 编程。现在我也很想知道我是否需要使用原生 javascript(难以阅读的程序)或 lodash 方式(易于阅读的程序)?
  • @SandeepSharma 使用您认为最适合您的需求和要求的东西。如果您已经拥有 Lodash,我认为值得坚持使用它。 Lodash 的 API 就是 Javascript 的语义。由于它是服务器端的,所以没有真正的 反对使用 Lodash 的论据——在客户端,它是一个庞大的库,但谁在乎服务器上的库大小?没有人。有微小的性能影响,但不足以真正产生影响。
  • @SandeepSharma 此外,Javascript 程序不必难以阅读。如果你的 Javascript 难以阅读,那是因为你让它变得不必要地复杂了。如果您花时间订阅适当的模式,JS 可以像 Lodash 一样简单明了。毕竟,Lodash Javascript。
  • @SandeepSharma 无论如何,如果此答案正确回答了您的原始问题,您应该将其标记为已接受的答案。
  • 您已将 item[0] 固定为第零个索引。
【解决方案2】:

具有讽刺意味的是,在没有任何库的情况下实现起来并不难。

Object.keys(obj).filter(x => obj[x].includes("c"))[0]

【讨论】:

  • 好点!你甚至可以使用.find(...) 而不是.filter(...)[0]Object.keys(obj).find(x =&gt; obj[x].includes("c"))
【解决方案3】:

这里有一个来自未来的单线答案。目前只适用于 Firefox 47 上。 ES7 提案的一部分。

var obj = {
  "01": ["a","b"],
  "03": ["c","d"],
  "04": ["e","c"]
},
    res = Object.entries(obj).find(e => e[1].includes("c"))[0];
document.write(res);

【讨论】:

  • 我相信 is not 是 ES7 的一部分,而不是 ES8。
  • 您可能应该更新find 条件,因为现在您不是在搜索整个数组,而是只搜索第一项。
  • @Роман Парадеев 是的,你是对的,我误解了引号。我会相应地更正。顺便说一句,您的解决方案是完美的,值得一个 +。
【解决方案4】:

作为替代解决方案:考虑使用 Object.keysArray.some 函数的原生 Javascript 方法:

var obj = {"01": ["a","b"],"03": ["c","d"],"04": ["e","c"]},
        search_str = "c", key = "";

Object.keys(obj).some(function(k) { return obj[k].indexOf(search_str) !== -1 && (key = k); });
// the same with ES6 syntax:
// Object.keys(obj).some((k) => obj[k].indexOf(search_str) !== -1 && (key = k));

console.log(key);  // "03"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多