2015-12-30 16 views
9

Tôi có một mảng nặng như thế này:Nhóm của mảng và thêm lĩnh vực và mảng phụ trong mảng chính

[ 
    {Id: 1, Name: 'Red', optionName: 'Color'}, 
    {Id: 2, Name: 'Yellow', optionName: 'Color'}, 
    {Id: 3, Name: 'Blue', optionName: 'Color'}, 
    {Id: 4, Name: 'Green', optionName: 'Color'}, 
    {Id: 7, Name: 'Black', optionName: 'Color'}, 
    {Id: 8, Name: 'S', optionName: 'Size'}, 
    {Id: 11, Name: 'M', optionName: 'Size'}, 
    {Id: 12, Name: 'L', optionName: 'Size'}, 
    {Id: 13, Name: 'XL', optionName: 'Size'}, 
    {Id: 14, Name: 'XXL', optionName: 'Size'} 
] 

Những gì tôi cần làm là để nhóm chúng bởi optionName và có hai hàng trong mảng chính như này:

[ 
    { 
    Name: 'Color', 
    Data:[{Id: 1, Name: 'Red'}, 
      {Id: 2, Name: 'Yellow'}, 
      {Id: 3, Name: 'Blue'}, 
      {Id: 4, Name: 'Green'}, 
      {Id: 7, Name: 'Black'}] 
    }, { 
    Name: 'Size', 
    Data:[{Id: 8, Name: 'S'}, 
      {Id: 11, Name: 'M'}, 
      {Id: 12, Name: 'L'}, 
      {Id: 13, Name: 'XL'}, 
      {Id: 14, Name: 'XXL'}] 
    } 
] 

Làm cách nào để thực hiện nó trong javascript?

Trả lời

11

Đây là đoạn trích tôi đã viết cho các loại tình huống này. Bạn có thể thêm chức năng này vào tất cả các mảng của mình:

Object.defineProperty(Array.prototype, 'group', { 
    enumerable: false, 
    value: function (key) { 
    var map = {}; 
    this.forEach(function (e) { 
     var k = key(e); 
     map[k] = map[k] || []; 
     map[k].push(e); 
    }); 
    return Object.keys(map).map(function (k) { 
     return {key: k, data: map[k]}; 
    }); 
    } 
}); 

Bạn có thể sử dụng nó như thế này. Bạn chỉ có thể chuyển một hàm xác định cách bạn muốn nhóm dữ liệu của mình.

var newArray = arr.group(function (item) { 
    return item.optionName; 
}); 

Working Fiddle

Nếu bạn cần, bạn có thể thay thế {key: k, data: map[k]} với {Name: k, Data: map[k]}.


Đây cũng là nhỏ gọn hơn ES6 phiên bản mã trên:

Object.defineProperty(Array.prototype, 'group', { 
    enumerable: false, 
    value: function (key) { 
    let map = {}; 
    this.map(e => ({k: key(e), d: e})).forEach(e => { 
     map[e.k] = map[e.k] || []; 
     map[e.k].push(e.d); 
    }); 
    return Object.keys(map).map(k => ({key: k, data: map[k]})); 
    } 
}); 

Sử dụng nó như thế này:

let newArray = arr.group(item => item.optionName)) 
3

Bạn có thể sử dụng giảm gấp đôi để có được những resultset bạn cần:

var color = list.reduce(function(memo, item) { 
    if (item.optionName === 'Color') { 
    memo.push({ 
     Id: item.Id, 
     Name: item.Name 
    }); 
    } 
    return memo; 
}, []); 

var size = list.reduce(function(memo, item) { 
    if (item.optionName === 'Size') { 
    memo.push({ 
     Id: item.Id, 
     Name: item.Name 
    }); 
    } 
    return memo; 
}, []); 

var result = [{ 
    Name: 'Color', Data: color 
}, { 
    Name: 'Size', Data: size 
}]; 

danh sách biến là danh sách đầu tiên của bạn.

Hy vọng điều này sẽ hữu ích.

0
var originalList = [ { Id: 1, Name: 'Red', optionName: 'Color' }, 
    { Id: 2, Name: 'Yellow', optionName: 'Color' }, 
    { Id: 3, Name: 'Blue', optionName: 'Color' }, 
    { Id: 4, Name: 'Green', optionName: 'Color' }, 
    { Id: 7, Name: 'Black', optionName: 'Color' }, 
    { Id: 8, Name: 'S', optionName: 'Size' }, 
    { Id: 11, Name: 'M', optionName: 'Size' }, 
    { Id: 12, Name: 'L', optionName: 'Size' }, 
    { Id: 13, Name: 'XL', optionName: 'Size' }, 
    { Id: 14, Name: 'XXL', optionName: 'Size' } ]; 

var output = [{ Name: "Color", Data: [] },{ Name: "Size", Data: [] }] ; 

originalList.map(function(entry){ 
    if (entry.optionName === "Color") output[0].Data.push({ Id: entry.Id, Name: entry.Name }); 
    if (entry.optionName === "Size") output[1].Data.push({ Id: entry.Id, Name: entry.Name }); 
}); 
0
'use strict' 

let l = [ { Id: 1, Name: 'Red', optionName: 'Color' }, 
      { Id: 2, Name: 'Yellow', optionName: 'Color' }, 
      { Id: 3, Name: 'Blue', optionName: 'Color' }, 
    { Id: 4, Name: 'Green', optionName: 'Color' }, 
    { Id: 7, Name: 'Black', optionName: 'Color' }, 
    { Id: 8, Name: 'S', optionName: 'Size' }, 
    { Id: 11, Name: 'M', optionName: 'Size' }, 
    { Id: 12, Name: 'L', optionName: 'Size' }, 
    { Id: 13, Name: 'XL', optionName: 'Size' }, 
    { Id: 14, Name: 'XXL', optionName: 'Size' } ]; 


let color = []; 
let size = []; 

l.forEach(element => { 
    if (element['optionName'] === 'Color') { 
     color.push({'Id': element.Id, 'Name': element.Name}); 
    } else { 
     size.push({'Id': element.Id, 'Name': element.Name}); 
    } 
}); 


console.log(color); 
console.log(size); 

Bạn có thể thử phương pháp này.

0

Tất cả các câu trả lời đều dẫn đến cùng một kết quả, vì vậy tất cả các câu trả lời đều thuộc về sở thích cá nhân (hoặc nguyên tắc của công ty) về cách giải quyết vấn đề này.

// ES5 (traditional javascript) version 
function groupByOptionName(list, optionName) { 
    return list 
     // filter out any item whose optionName does not match the desired name 
     .filter(function(item) { 
      return item.optionName === optionName; 
     }) 
     // map the item into the desired shape 
     // (appears to be everything except optionName itself 
     .map(function(item) { 
      return { 
       Id: item.Id, 
       Name: item.Name 
      }; 
     }) 
} 

// ES2015/ES6 version 
function groupByOptionName(list, optionName) { 
    return list 
     // filter out any item whose optionName does not match the desired name 
     .filter(item => item.optionName === optionName) 
     // map the item into the desired shape 
     // (appears to be everything except optionName itself 
     .map(item => { 
      Id: item.Id, 
      Name: item.Name 
     }); 
} 

Chức năng này sẽ cho phép bạn lập trình kết quả mong muốn như sau:

var output = [ 
    {Name: 'Color', Data: groupByOptionName(list, 'Color')}, 
    {Name: 'Size', Data: groupByOptionName(list, 'Size')}, 
]; 
// the ES2015/ES6 version of this code would replace var with let 

Mặc dù mã tự khác, nó là rất giống với câu trả lời khác, với chỉ một biến thể của các bước cần thiết. Bạn cũng có thể chọn để loại bỏ bất kỳ tên tùy chọn mã hóa nào (ColorSize) bằng cách giải nén những aswel, điều này sẽ cho phép đầu vào năng động hơn, nhưng cũng có thể giới thiệu nhiều xử lý thực sự cần thiết hơn.

// ES5 (traditional javascript) version 
function getOptionNames(list) { 
    return list 
     // map the array into a list of optionNames 
     .map(function(item) { 
      return item.optionName; 
     }) 
     // remove duplicates 
     .filter(function(item, index, all) { 
      return all.indexOf(item) === index; 
     }); 
} 

// ES2015/ES6 version (does exactly the same as the one above) 
function getOptionNames(list) { 
    return list 
     // map the array into a list of optionNames 
     .map(item => item.optionName) 
     // remove duplicates 
     .filter((item, index, all) => all.indexOf(item) === index); 
} 

nào cho phép kết quả để được hoàn toàn dựa trên các dữ liệu đầu vào:

// ES5 (traditional javascript) version 
var output = getOptionNames(list) 
     // map the names into the desired structure 
     .map(function(buffer, name) { 
      return { 
       Name: name, 
       Data: groupByOptionName(list, name) 
      }; 
     }); 

// ES2015/ES6 version (does exactly the same as the one above) 
var output = getOptionNames(list) 
     // map the names into the desired structure 
     .map((buffer, name) => { 
      Name: name, 
      Data: groupByOptionName(list, name) 
     }); 

Bằng cách viết tất cả các bước dữ liệu mangling trong bước consice ngắn bạn muốn làm bản thân bạn (đặc biệt là bản thân tương lai của bạn) một ưu tiên nếu mã này cần được điều chỉnh.

Nếu tập dữ liệu thực sự nặng (theo số rất nhiều dữ liệu), bạn cũng phải đảm bảo giữ số bản sao bạn giữ trong bộ nhớ bị giới hạn. Ví dụ: nếu bạn không bao giờ cần tập dữ liệu gốc, hãy đảm bảo rằng nó có thể được thu thập rác (do không có biến chứa bên ngoài phạm vi nơi bạn nhận dữ liệu)

+0

Tốt tóm tắt Rogier, chỉ là một sự điều chỉnh khó khăn: bạn đề cập đến những giải pháp có sẵn trong ES6 +, nhưng nguyên mẫu mảng fil ter, bản đồ và giảm có sẵn từ ES5.1 (2011) và được hỗ trợ bởi IE9 +, FF3 + và tất cả các phiên bản chrome. –

+0

@AhmetCetin Tôi không hoàn toàn chắc chắn nếu tôi hiểu ý bạn là gì, trong ví dụ của tôi, tôi cung cấp cú pháp ES5 (.1) aswel giống như hàm được viết trong ES6 +. Có lẽ tôi cần phải làm rõ các hàm đầu tiên là ES5 (.1)? –

+0

bạn nói đúng, tôi đã bỏ lỡ điều đó, bạn đã sử dụng ký hiệu mũi tên chất béo trong ES6. Nên hiểu rõ hơn nếu bạn đề cập đến cú pháp khác là hợp lệ cho ES5.1. Khi tôi đọc lần đầu tiên, tôi nghĩ bạn có nghĩa là tất cả các giải pháp hợp lệ cho ES6. –

1

Đây là đoạn trích tôi đã viết cho tình huống của mình trong chức năng ứng dụng của tôi trong tất cả các mảng. Đoạn mã này được sử dụng trong ứng dụng nút js. Tất cả các bên trên là đưa ra giải pháp nhưng tôi đã tìm thấy một số vấn đề ở phía máy chủ trong nút js. Đoạn mã này là người dùng đầy đủ của tôi ....

var Data= [ 
    { Id: 1, Name: 'Red', optionName: 'Color' }, 
     { Id: 2, Name: 'Yellow', optionName: 'Color' }, 
     { Id: 3, Name: 'Blue', optionName: 'Color' }, 
     { Id: 4, Name: 'Green', optionName: 'Color' }, 
     { Id: 7, Name: 'Black', optionName: 'Color' }, 
     { Id: 8, Name: 'S', optionName: 'Size' }, 
     { Id: 11, Name: 'M', optionName: 'Size' }, 
     { Id: 12, Name: 'L', optionName: 'Size' }, 
     { Id: 13, Name: 'XL', optionName: 'Size' }, 
     { Id: 14, Name: 'XXL', optionName: 'Size' } ]; 

    function groupBy(arr, key) { 
       var newArr = [], 
        types = {}, 
        newItem, i, j, cur; 
       for (i = 0, j = arr.length; i < j; i++) { 
        cur = arr[i]; 
        if (!(cur[key] in types)) { 
         types[cur[key]] = { type: cur[key], data: [] }; 
         newArr.push(types[cur[key]]); 
        } 
        types[cur[key]].data.push(cur); 
       } 
       return newArr; 
} 

Tôi sử dụng nó như thế này. Tôi chỉ chuyển một hàm xác định cách bạn muốn nhóm dữ liệu của mình.

filterData= groupBy(Data,'optionName'); 

Kết quả của đoạn mã này đầu ra mã .....

[ 
{"type":"Color","data":[{"Id":1,"Name":"Red","optionName":"Color"}, 
         {"Id":2,"Name":"Yellow","optionName":"Color"}, 
         {"Id":3,"Name":"Blue","optionName":"Color"}, 
         {"Id":4,"Name":"Green","optionName":"Color"}, 
         {"Id":7,"Name":"Black","optionName":"Color"}]}, 
{"type":"Size","data":[{"Id":8,"Name":"S","optionName":"Size"}, 
         {"Id":11,"Name":"M","optionName":"Size"}, 
         {"Id":12,"Name":"L","optionName":"Size"}, 
         {"Id":13,"Name":"XL","optionName":"Size"}, 
         {"Id":14,"Name":"XXL","optionName":"Size"}]} 
] 

Show on fiddle

0

Cách sử dụng:

groupValues([ 
    { color: 'blue', value: 100 }, 
    { color: 'blue', value: 75 }, 
    { color: 'yellow', value: 50 }, 
    { color: 'yellow', value: 25 } 
], 'color') 

Kết quả:

[ 
    [{ color: 'blue', value: 100 }, { color: 'blue', value: 75 }], 
    [{ color: 'yellow', value: 50 }, { color: 'yellow', value: 25 }] 
] 

Chức năng:

const groupValues = function(arr, key) { 
    const mapped = {} 
    arr.forEach(el => { 
     const actualKey = el[key] 
     if(!mapped.hasOwnProperty(actualKey)) mapped[actualKey] = [] 

     mapped[actualKey].push(el) 
    }) 
    return Object.keys(mapped).map(el => mapped[el]) 
} 
3

giải pháp Một ES6 sử dụng Bản đồ đối tượng:

function groupBy(arr, key) { 
 
    \t return arr.reduce(
 
     (sum, item) => { 
 
     \t const groupByVal = item[key]; 
 
     groupedItems = sum.get(groupByVal) || []; 
 
     groupedItems.push(item); 
 
     \t return sum.set(groupByVal, groupedItems); 
 
     }, 
 
     new Map() 
 
    ); 
 
} 
 

 
var Data = [ 
 
{ Id: 1, Name: 'Red', optionName: 'Color' }, 
 
    { Id: 2, Name: 'Yellow', optionName: 'Color' }, 
 
    { Id: 3, Name: 'Blue', optionName: 'Color' }, 
 
    { Id: 4, Name: 'Green', optionName: 'Color' }, 
 
    { Id: 7, Name: 'Black', optionName: 'Color' }, 
 
    { Id: 8, Name: 'S', optionName: 'Size' }, 
 
    { Id: 11, Name: 'M', optionName: 'Size' }, 
 
    { Id: 12, Name: 'L', optionName: 'Size' }, 
 
    { Id: 13, Name: 'XL', optionName: 'Size' }, 
 
    { Id: 14, Name: 'XXL', optionName: 'Size' } ]; 
 

 
document.getElementById("showArray").innerHTML =JSON.stringify([...groupBy(Data, 'optionName')], null, 4);
<pre id="showArray"></pre>

Các vấn đề liên quan