【问题标题】:Most terse way to find a string value in an object of arrays?在数组对象中查找字符串值的最简洁方法?
【发布时间】:2017-05-25 05:17:11
【问题描述】:

所以我有一堆状态代码,在一个对象(来自 API)中,返回如下:

{
  "location": [
    "HOME_ADDRESS_INCOMPLETE",
    "HOME_MISSING_ADDRESS"
  ],
  "basics": [
    "HOME_MISSING_TYPE"
  ],
  "description": [
    "HOME_MISSING_DESCRIPTION"
  ],
  "immersions": [
    "AT_LEAST_ONE_STAY_REQUIRED",
    "SIMPLE_STAY_MISSING_HOURS",
    "SIMPLE_STAY_MISSING_OFFERED_LANGUAGES",
    "TANDEM_STAY_MISSING_HOURS",
    "TANDEM_STAY_MISSING_OFFERED_LANGUAGES",
    "TANDEM_STAY_MISSING_INTERESTED_LANGUAGES",
    "TEACHER_STAY_MISSING_HOURLY_PRICE",
    "TEACHER_STAY_MISSING_OFFERED_LANGUAGES",
    "TEACHER_STAY_MISSING_WEEKLY_PACKAGES"
  ],
  "rooms": [
    "NO_ROOMS"
  ],
  "photos": [
    "AT_LEAST_ONE_HOME_IMAGE_REQUIRED"
  ],
  "pricing": [
    "MISSING_CURRENCY",
    "SERVICE_WITHOUT_PRICE",
    "DISCOUNT_WITHOUT_PERCENT",
    "ROOM_WITHOUT_PRICE"
  ]
}

诸如location 之类的键名与设置向导中的一个步骤相关,用户必须根据缺少的内容放置该步骤,该步骤由HOME_ADDRESS_INCOMPLETE 等常量表示。

从这个对象和一个常量(如MISSING_CURRENCY)开始,然后返回该常量数组所属键的名称,最简洁或清晰的方法是什么?

这是我目前所拥有的,但它所做的只是返回数组本身:

const activeStep = Object.values(HomeStatusCodes).filter(statusArray => {
  return statusArray.includes(homeActivationResponse.code)
})

【问题讨论】:

  • @Soviut 更新问题
  • 所以在你的例子中,搜索MISSING_CURRENCY 应该返回"pricing"?

标签: javascript arrays loops ecmascript-6 constants


【解决方案1】:

Array#find(在该结构的键数组上,来自Object.keys)加上Array#indexOf 应该这样做:

function find(value) {
  return Object.keys(data).find(function(key) {
    return data[key].indexOf(value) != -1;
  });
}

请注意,Array#find 是 ES2015 中的新功能,但可以很容易地填充/填充。

例子:

var data = {
  "location": [
    "HOME_ADDRESS_INCOMPLETE",
    "HOME_MISSING_ADDRESS"
  ],
  "basics": [
    "HOME_MISSING_TYPE"
  ],
  "description": [
    "HOME_MISSING_DESCRIPTION"
  ],
  "immersions": [
    "AT_LEAST_ONE_STAY_REQUIRED",
    "SIMPLE_STAY_MISSING_HOURS",
    "SIMPLE_STAY_MISSING_OFFERED_LANGUAGES",
    "TANDEM_STAY_MISSING_HOURS",
    "TANDEM_STAY_MISSING_OFFERED_LANGUAGES",
    "TANDEM_STAY_MISSING_INTERESTED_LANGUAGES",
    "TEACHER_STAY_MISSING_HOURLY_PRICE",
    "TEACHER_STAY_MISSING_OFFERED_LANGUAGES",
    "TEACHER_STAY_MISSING_WEEKLY_PACKAGES"
  ],
  "rooms": [
    "NO_ROOMS"
  ],
  "photos": [
    "AT_LEAST_ONE_HOME_IMAGE_REQUIRED"
  ],
  "pricing": [
    "MISSING_CURRENCY",
    "SERVICE_WITHOUT_PRICE",
    "DISCOUNT_WITHOUT_PERCENT",
    "ROOM_WITHOUT_PRICE"
  ]
};

function find(value) {
  return Object.keys(data).find(function(key) {
    return data[key].indexOf(value) != -1;
  });
}

console.log(find("MISSING_CURRENCY"));

使用 ES2015 语法会更简洁:

const find = value =>
  Object.keys(data).find(key => data[key].indexOf(value) != -1);

(是的,这确实是一个功能。)这是支持 ES2015 的浏览器的实时版本:

var data = {
  "location": [
    "HOME_ADDRESS_INCOMPLETE",
    "HOME_MISSING_ADDRESS"
  ],
  "basics": [
    "HOME_MISSING_TYPE"
  ],
  "description": [
    "HOME_MISSING_DESCRIPTION"
  ],
  "immersions": [
    "AT_LEAST_ONE_STAY_REQUIRED",
    "SIMPLE_STAY_MISSING_HOURS",
    "SIMPLE_STAY_MISSING_OFFERED_LANGUAGES",
    "TANDEM_STAY_MISSING_HOURS",
    "TANDEM_STAY_MISSING_OFFERED_LANGUAGES",
    "TANDEM_STAY_MISSING_INTERESTED_LANGUAGES",
    "TEACHER_STAY_MISSING_HOURLY_PRICE",
    "TEACHER_STAY_MISSING_OFFERED_LANGUAGES",
    "TEACHER_STAY_MISSING_WEEKLY_PACKAGES"
  ],
  "rooms": [
    "NO_ROOMS"
  ],
  "photos": [
    "AT_LEAST_ONE_HOME_IMAGE_REQUIRED"
  ],
  "pricing": [
    "MISSING_CURRENCY",
    "SERVICE_WITHOUT_PRICE",
    "DISCOUNT_WITHOUT_PERCENT",
    "ROOM_WITHOUT_PRICE"
  ]
};

const find = value =>
  Object.keys(data).find(key => data[key].indexOf(value) != -1);

console.log(find("MISSING_CURRENCY"));

【讨论】:

  • @Drix:很好。 :-) 这就是我从 ES5 开始,然后将它的一部分转换为 ES2015...
【解决方案2】:

您可以迭代键并找到包含所需项目的属性。

function getKey(object, item) {
    return Object.keys(object).find(k => object[k].includes(item));
}

var data = { "location": ["HOME_ADDRESS_INCOMPLETE", "HOME_MISSING_ADDRESS"], "basics": ["HOME_MISSING_TYPE"], "description": ["HOME_MISSING_DESCRIPTION"], "immersions": ["AT_LEAST_ONE_STAY_REQUIRED", "SIMPLE_STAY_MISSING_HOURS", "SIMPLE_STAY_MISSING_OFFERED_LANGUAGES", "TANDEM_STAY_MISSING_HOURS", "TANDEM_STAY_MISSING_OFFERED_LANGUAGES", "TANDEM_STAY_MISSING_INTERESTED_LANGUAGES", "TEACHER_STAY_MISSING_HOURLY_PRICE", "TEACHER_STAY_MISSING_OFFERED_LANGUAGES", "TEACHER_STAY_MISSING_WEEKLY_PACKAGES"], "rooms": ["NO_ROOMS"], "photos": ["AT_LEAST_ONE_HOME_IMAGE_REQUIRED"], "pricing": ["MISSING_CURRENCY", "SERVICE_WITHOUT_PRICE", "DISCOUNT_WITHOUT_PERCENT", "ROOM_WITHOUT_PRICE"] };

console.log(getKey(data, 'MISSING_CURRENCY'));

【讨论】:

    【解决方案3】:

    我会去查找地图:

    const stepByStatusCode = new Map()
    for (const step in HomeStatusCodes) {
        for (const code of HomeStatusCodes[step])
            stepByStatusCode.set(code, step);
    

    然后你可以以最简洁的方式使用它

    const activeStep = stepByStatusCode.get(homeActivationResponse.code);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-15
      • 2016-06-22
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      相关资源
      最近更新 更多