【问题标题】:Object containing arrays of objects and arrays of strings包含对象数组和字符串数组的对象
【发布时间】:2019-06-06 17:04:39
【问题描述】:

我有一个看起来像这样的对象:

var obj = {
  "array1": [
    {"label": "something1", "ref": "option2a"},
    {"label": "something2", "ref": "option2b"},
    {"label": "something3", "ref": "option2a"},
    {"label": "something4", "ref": "option2a"},
    {"label": "something5 is the longest", "ref": "option2a"}
  ],
  array2: [
    "arrayItem1",
    "array Item 2"
  ]
}

此对象包含对象数组和字符串数组。我想遍历每个具有标签的对象并返回最长的标签。在前面的示例中,预期的输出 id:

"something5 is the longest".

我尝试了以下方法:

function getLongest(object, key) {
  return Object.values(object).reduce((l, v) => {
    if (object.hasOwnProperty(key)) {
      if (key in v)
        return Math.max(l, v[key].length);
      if (v && typeof v === 'object')
        return Math.max(l, getLongest(v, key));
      return l;
    }
  }, 0);
}

但是这给了我一个错误,因为它找不到 label 的属性 array2 中的项目。

【问题讨论】:

  • @Mandalina,'array1' 和 'array2' 是否要相互比较?分别地?还是只有带有“标签”键的数组(例如 'array1')?
  • 嘿@SunnyPatel 是的,我只需要获取带有“标签”键的数组;像array1。

标签: javascript jquery arrays


【解决方案1】:

这里有一种方法,它使用了 reduce() 的动画方法,而不是 Object.Values()

var obj = {
    "array1": [
        {"label": "something1", "ref": "option2a"},
        {"label": "something2", "ref": "option2b"},
        {"label": "something3", "ref": "option2ahgf"},
        {"label": "something4", "ref": "option2a"},
        {"label": "I'm not the longest", "ref": "option2a"}
    ],
    array2: [
        "arrayItem1",
        {"label": "something5 is the longest", "ref": "option2a"},
        "array Item 2"
    ],
    array3: [
        {"label": "somethingX", "ref": "option2X"},
        {"label": "somethingY", "ref": "option2Y"}
    ]
}

const getLongest = (obj, key) =>
{
    let r = Object.values(obj).reduce((res, curr) =>
    {
        if (!Array.isArray(curr))
            return res;

        let newMax = curr.reduce(
            (r, c) => c[[key]] && (c[[key]].length > r.length) ? c[[key]] : r,
            ""
        );

        res = newMax.length > res.length ? newMax : res;
        return res;

    }, "");

    return r;
}

console.log(getLongest(obj, "label"));
console.log(getLongest(obj, "ref"));

【讨论】:

  • 我刚刚更新了它以将逻辑包装在一个函数中并对其进行更多概括。
【解决方案2】:

既然你提到了jQuery,我已经提供了一个解决方案,它使用jQuery.map 来迭代你的外部对象,并使用array.reduceobj 中的每个数组值中只产生一个结果。

var obj = {
  "array1": [{
      "label": "something1",
      "ref": "option2a"
    },
    {
      "label": "something2",
      "ref": "option2b"
    },
    {
      "label": "something3",
      "ref": "option2a"
    },
    {
      "label": "something4",
      "ref": "option2a"
    },
    {
      "label": "something5 is the longest",
      "ref": "option2a"
    }
  ],
  array2: [
    "arrayItem1",
    "array Item 2"
  ]
}
function getLongest(curr, next) {
  return !Object.keys(next).includes("label") || curr.label.length > next.label.length ? curr : next;
}

var reduced = $.map(obj, item => item.reduce(getLongest, {"label": ""}))
console.log(reduced);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

这基本上会遍历obj 中的每个键的值,并将数组缩减为具有最长label 标签的单个对象,如果它甚至有label 键的话。如果没有,它会返回一个没有标签的默认对象,并使用具有混合对象/字符串的数组。

所以它返回一个匹配键为obj的对象。

【讨论】:

    【解决方案3】:

    示例:

    // object declaration
    var obj = {
      "array1": [{
          "label": "something1",
          "ref": "option2a"
        },
        {
          "label": "something2",
          "ref": "option2b"
        },
        {
          "label": "something3",
          "ref": "option2a"
        },
        {
          "label": "something4",
          "ref": "option2a"
        },
        {
          "label": "something5 is the longest",
          "ref": "option2a"
        }
      ],
      array2: [
        "arrayItem1",
        "array Item 2"
      ]
    };
    
    // iterate over all items in obj
    for (var propertyName in obj) {
      // if the item is an object and is an array
      if (typeof obj[propertyName] === 'object' && Array.isArray(obj[propertyName])) {
        // if the array has at least one item and a property of label
        if (obj[propertyName].length > 0 && typeof obj[propertyName][0].label !== 'undefined') {
          // sort the array by length of label
          obj[propertyName].sort((a,b) => (a.label.length < b.label.length) ? 1 : ((b.label.length < a.label.length) ? -1 : 0));
          // console.log print the longest label
          console.log('longest label name:', obj[propertyName][0].label);
        }
      }
    }
    
    // output the whole obj
    console.log(obj);

    【讨论】:

    • 我不认为 OP 从字面上想要对它们进行排序。只需取回值最长的标签即可。
    • ` 我想对每个具有标签的对象进行排序并返回最长的标签。在这种情况下,它将返回“something5 is the long”`@SunnyPatel
    • “遍历每个”可以被认为是“遍历每个”。就像“整理论文”一样,你会“浏览”它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 2023-02-06
    • 1970-01-01
    • 2020-11-15
    • 2022-12-02
    • 2021-11-17
    相关资源
    最近更新 更多