代码之家  ›  专栏  ›  技术社区  ›  Sergino

如何将一个数组转换为另一个数组

  •  4
  • Sergino  · 技术社区  · 7 年前

    我在阵列中导航:

    const arr = [
      { name: "aa", type: "total", count: 28394 },
      { name: "aa", type: "featured", count: 4 },
      { name: "aa", type: "noAnswers", count: 5816 },
      { name: "ba", type: "total", count: 148902 },
      { name: "ba", type: "featured", count: 13 },
      { name: "ba", type: "noAnswers", count: 32527 },
      { name: "cc", type: "total", count: 120531 },
      { name: "cc", type: "featured", count: 6 },
      { name: "cc", type: "noAnswers", count: 24170 }
    ];
    
    
    const arrResult = [
      { name: "aa", total: 28394, featured: 4, noAnswers: 5816 },
      { name: "ba", total: 148902, featured: 13, noAnswers: 32527 },
      { name: "cc", total: 120531, featured: 6, noAnswers: 24170 }
    ];
    

    我想出了这个密码:

    let output = [];
    
    const unique = [...new Set(arr.map(item => item.name))];
    
    for(const key of unique) {
      let result = arr.filter(x => {
        return x.name === key;
      });
      output.push({
        name: key,
        // need to get the rest of the properties here
        // total
        // featured
        // noAnswers
      });
    }
    

    我唯一搞不懂的是如何获得房产名称。 有什么想法吗?

    6 回复  |  直到 7 年前
        1
  •  5
  •   Community Mohan Dere    6 年前

    你可以试试这样:

    想法:

    • 创建一个hashMap,以便通过 name .
    • 然后,向该组添加必要的属性。
    • 最后,在关键点上循环并创建最后一个添加了name属性的对象。

    const arr = [ { name: "aa", type: "total", count: 28394 }, { name: "aa", type: "featured", count: 4 }, { name: "aa", type: "noAnswers", count: 5816 }, { name: "ba", type: "total", count: 148902 }, { name: "ba", type: "featured", count: 13 }, { name: "ba", type: "noAnswers", count: 32527 }, { name: "cc", type: "total", count: 120531 }, { name: "cc", type: "featured", count: 6 }, { name: "cc", type: "noAnswers", count: 24170 } ];
    
    const hashMap = arr.reduce((acc, item) => {
      acc[item.name] = acc[item.name] || {};
      acc[item.name][item.type] = item.count;
      return acc;
    }, {});
    
    const result = Object.keys(hashMap).map((name) => Object.assign({}, {name}, hashMap[name] ));
    
    console.log(result)

    工作:

    我所做的是为每一个新的对象创建一个新的对象 名称 .所以,这个: acc[item.name] = acc[item.name] || {}; 检查条目是否不可用。

    • 如果不可用,请返回一个新对象。
    • 如果可用,返回同一对象的引用。

    因此,对于任何给定的名称,您将只引用同一个对象。

    现在: acc[item.name][item.type] = item.count 设置属性。因为我们指的是同一个对象,所以在一个地方设置属性。所以如果你有重复的条目,比如

    [
        { name: "aa", type: "total", count: 28394 },
        { name: "aa", type: "total", count: 123},
    ]
    

    产量将有所增加 total: 123 相反

    最后,你有一个类似的结构:

    {
      aa: {
        total: <something>,
        feature: <something>,
        ...
      }
    }
    

    现在,您所要做的就是在这个对象中合并名称并返回值。还可以使用创建对象 名称 属性作为默认值( 正如 adiga ).这是我在回答问题时没有想到的。因此,赞扬而不是回答。

        2
  •  2
  •   adiga    7 年前

    你可以用 reduce 和 destructuring 这样地:

    这个想法是创建一个具有 key 作为 name 属性和值作为输出中所需的最终对象。所以,你可以简单地使用 Object.values 要获取最终数组,请执行以下操作:

    const arr=[{name:"aa",type:"total",count:28394},{name:"aa",type:"featured",count:4},{name:"aa",type:"noAnswers",count:5816},{name:"ba",type:"total",count:148902},{name:"ba",type:"featured",count:13},{name:"ba",type:"noAnswers",count:32527},{name:"cc",type:"total",count:120531},{name:"cc",type:"featured",count:6},{name:"cc",type:"noAnswers",count:24170}];
    
    const merged = arr.reduce((acc,{name,type,count}) =>
      ((acc[name] = acc[name] || {name})[type] = count, acc)
    ,{})
    
    console.log(Object.values(merged))

    这相当于:

    const arr=[{name:"aa",type:"total",count:28394},{name:"aa",type:"featured",count:4},{name:"aa",type:"noAnswers",count:5816},{name:"ba",type:"total",count:148902},{name:"ba",type:"featured",count:13},{name:"ba",type:"noAnswers",count:32527},{name:"cc",type:"total",count:120531},{name:"cc",type:"featured",count:6},{name:"cc",type:"noAnswers",count:24170}];
    
    /* Our goal is to create a merged object like this:
    {
      "aa": {
        "name": "aa",
        "total": 28394,
        "featured": 4,
        "noAnswers": 5816
      },
      "ba": {
        "name": "ba",
        "total": 148902,
        ....
      },
      "cc": {
        "name": "cc",
         ......
      }
    }
    
    The advantage of using object accumulator is we can access it like this: acc[name]
    */
    
    const merged = arr.reduce((acc, {name,type,count} /*Destructuring*/) => {
      /* if the accumulator doesn't have the current "name" key, 
       create new object
       else use the existing one;
       {name} is same as {name: name}
      */
      acc[name] = acc[name] || {name};
      
      /* To the inner object, 
          add a key with the "type" value and assign it to "count" value
      */
      acc[name][type] = count;
      
      // return the accumulator
      return acc;
    }, {})
    
    // use Object.values to get the value part of the merged obejct into an array
    console.log(Object.values(merged))
        3
  •  1
  •   pr0p    7 年前
    var op = {name : key};
    
      for(i=0; i < result.length; i++){
        op[result[i].type] = result[i].count;
      }
    
      output.push(op);
    

    只要加上这个就行了。然而,你的代码并不是最有效的。 基于名称的哈希将使其更快

    const arr = [
      { name: "aa", type: "total", count: 28394 },
      { name: "aa", type: "featured", count: 4 },
      { name: "aa", type: "noAnswers", count: 5816 },
      { name: "ba", type: "total", count: 148902 },
      { name: "ba", type: "featured", count: 13 },
      { name: "ba", type: "noAnswers", count: 32527 },
      { name: "cc", type: "total", count: 120531 },
      { name: "cc", type: "featured", count: 6 },
      { name: "cc", type: "noAnswers", count: 24170 }
    ];
    
    let output = [];
    
    const unique = [...new Set(arr.map(item => item.name))];
    
    for(const key of unique) {
      let result = arr.filter(x => {
        return x.name === key;
      });
      
      var op = {name : key};
      
      for(i=0; i < result.length; i++){
        op[result[i].type] = result[i].count;
      }
      
      output.push(op);
    }
    
    console.log(output);

    以下是最有效的方法:

    const arr = [
          { name: "aa", type: "total", count: 28394 },
          { name: "aa", type: "featured", count: 4 },
          { name: "aa", type: "noAnswers", count: 5816 },
          { name: "ba", type: "total", count: 148902 },
          { name: "ba", type: "featured", count: 13 },
          { name: "ba", type: "noAnswers", count: 32527 },
          { name: "cc", type: "total", count: 120531 },
          { name: "cc", type: "featured", count: 6 },
          { name: "cc", type: "noAnswers", count: 24170 }
        ];
     
     var hash = {};
     var result = [];
     
     for(var i=0; i < arr.length; i++){
      if(!arr[i].name in hash)
        hash[arr[i].name] = {}
      let temp = {};
      temp[arr[i].type] = arr[i].count;
      hash[arr[i].name] = Object.assign(temp, hash[arr[i].name]);  
     }
     
     for(var key in hash)
      result.push({name : key, ...hash[key]})
      
    console.log(result)
     
        4
  •  0
  •   Ashique    7 年前

    你可以用 find javascript操作符从中获取所需的行 arrResult 如下图所示更改代码-

    for(const key of unique) {
      let result = arr.filter(x => {
        return x.name === key;
      });
      var currResult = arrResult.find(x => x.name == key);
      output.push({
        name: key,
        // need to get the rest of the properties here
        total: currResult.total,
        featured: currResult.featured,
        noAnswers: currResult.noAnswers
      });
    }
    

    JSFiddle: https://jsfiddle.net/ashhaq12345/z8royg5w/

        5
  •  0
  •   Nikita Malyschkin    7 年前

    const arr = [
      { name: "aa", type: "total", count: 28394 },
      { name: "aa", type: "featured", count: 4 },
      { name: "aa", type: "noAnswers", count: 5816 },
      { name: "ba", type: "total", count: 148902 },
      { name: "ba", type: "featured", count: 13 },
      { name: "ba", type: "noAnswers", count: 32527 },
      { name: "cc", type: "total", count: 120531 },
      { name: "cc", type: "featured", count: 6 },
      { name: "cc", type: "noAnswers", count: 24170 }
    ];
    
    const names = [...new Set(arr.map(item => item.name))]
    const output = {};
    
    names.forEach(name => {output[name] = {}});
    
    arr.forEach(item => {
      output[item.name][item.type] = item.count
    });
    
    const result = Object.entries(output).map(([name, rest]) => ({name, ...rest}))
    console.log(result);
    
    const arrResult = [
      { name: "aa", total: 28394, featured: 4, noAnswers: 5816 },
      { name: "ba", total: 148902, featured: 13, noAnswers: 32527 },
      { name: "cc", total: 120531, featured: 6, noAnswers: 24170 }
    ];
        6
  •  0
  •   Sudhir Ojha    7 年前

    你可以简单地使用for循环在你的数组上进行迭代,得到一个临时数组,得到map,然后使用所需的数据填充map,然后像下面这样将map推到临时数组中。

    const arr = [
      { name: "aa", type: "total", count: 28394 },
      { name: "aa", type: "featured", count: 4 },
      { name: "aa", type: "noAnswers", count: 5816 },
      { name: "ba", type: "total", count: 148902 },
      { name: "ba", type: "featured", count: 13 },
      { name: "ba", type: "noAnswers", count: 32527 },
      { name: "cc", type: "total", count: 120531 },
      { name: "cc", type: "featured", count: 6 },
      { name: "cc", type: "noAnswers", count: 24170 }
    ];
    
    let result = [];
    for( var i = 0; i < arr.length; i++)
    {
       let data = {};
       if( arr[i].type == 'total')
       {
          data.name = arr[i].name;
          data.total = arr[i].count;
          data.featured = arr[i+1].count;
          data.noAnswers = arr[i+2].count;
          result.push(data);
       }
    }
    
    console.log(result);